I created a trait and i want to be able to get the namespace of the class using the trait. is this possible? self::class gives me the class name of the parent but not the entire namespace
You can use ReflectionClass->getNamespaceName() with the reflection of self::class.
MyTrait.php
namespace MyTraitNamespace;
Trait MyTrait{
public function echoClassNamespace()
{
$ref = new \ReflectionClass(self::class);
echo $ref->getNamespaceName(); //Will echo MyClassNamespace
}
public function echoTraitNamespace()
{
echo __NAMESPACE__; //Will echo MyTraitNamespace
}
}
MyClass.php
namespace MyClassNamespace;
use MyTraitNamespace\MyTrait;
class MyClass{
use MyTrait;
}
Related
Overwrite namespace usage in extended class
Is it possible to overwrite the used namespace of the parent class without rewriting the function in the extended class?
For clarification i write down an example:
i have two classes like this:
namespace one;
class hey
{
public static function say()
{
echo "hey";
}
}
and
namespace two;
class hey
{
public static function say()
{
echo "ho";
}
}
Now i use on of the namespaces in this class:
use one\hey;
class saysomething
{
public static function main()
{
hey::say();
}
}
Now i want to extend the last class:
class extended extends saysomething
{
}
extended::main();
In this class i want to use namespace "two\one" without overwriting the function, is it possible? *f it is, how?
Thank you for your time.
You must define extended::main() within extended class, like this:
use two\hey;
class extended extends saysomething
{
public static function main()
{
hey::say(); // will call two/hey::say method
}
}
Namespaces won't help here.
I am trying to find answer of following question:
Function world() is defined in the namespace 'myapp\utils\hello.' Your code is in namespace 'myapp'
What is the correct way to import the hello namespace so you can use the world() function?
Following is my code which I am trying but I am getting this error:
Fatal error: Call to undefined function myapp\world()
My Code:
<?php
namespace myapp;
use myapp\utils\hello;
world();
namespace myapp\utils\hello;
function world()
{
echo 'yes world';
}
You may do this:
<?php
namespace myapp;
\myapp\utils\hello\world();
namespace myapp\utils\hello;
function world()
{
echo 'yes world';
}
Also, read more here Using namespaces.
This is intresting:
All versions of PHP that support namespaces support three kinds of
aliasing or importing: aliasing a class name, aliasing an interface
name, and aliasing a namespace name. PHP 5.6+ also allows aliasing or
importing function and constant names.
Simply, before PHP 5.6, you can not use use to import a function. It has to be in a class. But with PHP5.6+, you can do this:
<?php
namespace myapp;
use function myapp\utils\hello\world;
world();
namespace myapp\utils\hello;
function world()
{
echo 'yes world';
}
<?php
namespace myapp;
use myapp\utils\hello\world;
But you miss the class name:
<?php
namespace myapp;
use myapp\utils\hello\world; // now, you can create an instance of world
class foo
{
public function bar()
{
return (new world())->yourMethod();
}
}
And your world class:
<?php
namespace myapp;
class world
{
public function yourMethod()
{
return 'It works';
}
}
Be sure that you've (auto)loaded the required classes!
I'm having some trouble to call a function from a namespaced class in a different namespaced class. In the dummy example below I would like to know how to use Class2 within Class1. I'm getting the error:
Trait 'name1\name2\Class2' not found in class1.php
The code:
#file index.php
require "class1.php";
require "class2.php";
$class1 = new name1\Class1();
$class1->sayHello();
#file class1.php
namespace name1{
class Class1{
use name2\Class2;
public function sayHello(){
echo Class2::staticFunction();
}
}
}
#file class2.php
namespace name2{
class Class2{
public static function staticFunction(){
return "hello!";
}
}
}
Thank you for any advice.
Ok, so you've got several errors which I have fixed.
Here's the working code you need:
# index.php
include "class1.php";
include "class2.php";
$class1 = new name1\Class1();
$class1->sayHello();
# class1.php
namespace name1;
use name2\Class2;
class Class1{
public function sayHello(){
echo Class2::staticFunction();
}
}
# class2.php
namespace name2;
class Class2{
public static function staticFunction(){
return "hello!";
}
}
Some explanations:
When in class definition the use is used for using traits and not namespace
In PHP namespace need not be enclosed in curly brackets
In PHP you include files with include, include_once, require, or require_once, and not import
Inside your first class, your trait is calling class2 as use name2\Class2 but, you are still within the name1{} namespace, so in reality you are calling it as: use name1\name2\Class2
So, you need to change
use name2\Class2; to use \name2\Class2
Try this.
namespace name1{
use \name2\Class2;
class Class1{
public function sayHello(){
echo Class2::staticFunction();
}
}
}
#file class2.php
namespace name2{
class Class2{
public static staticFunction(){
return "hello!";
}
}
}
Also, another tip: If you are separating your classes in separate files, you do not need to separate them as in they way you have done. Just call the namespace simple as:
// file1.php
namespace person;
class name{}
//file2.php
namespace address;
class name{}
Why not drop the static method and just inject the class? Seems like going through extra work for something so simple. That's what function arguments are made for.
namespace name1{
use \name2\Class2;
class Class1{
public function sayHello($Class2){
echo $Class2->someFunction();
}
}
}
namespace name2{
class Class2{
public function someFunction(){
return "hello!";
}
}
}
#index.php
include "class1.php";
include "class2.php";
$Class1 = new name1\Class1();
$Class2 = new name2\Class2();
$Class1->sayHello($Class2);
//hello!
Let's say I have a simple class like this that uses a trait.
<?php namespace A\B;
use C\FooTrait;
class D {
use FooTrait;
}
And my trait looks like this.
<?php namespace C;
class FooTrait {
public function getBaseNamespace()
{
// code
}
}
My expected behavior would be the following:
<?php
$d = new D;
// Shoud be 'A\B';
$d->getBaseNamespace();
But so far I haven't been able to do this using the reflection API. Any clues?
This might be a bit more simple than using reflection.
If you are trying to determine it from within the trait method.
You can use:
public function getBaseNamespace()
{
return preg_replace('/(.+)\\\\[^\\\\]+/', '$1', __CLASS__);
}
My final implementation is the following.
<?php namespace Tools\Namespaces;
use ReflectionClass;
trait NamespaceTrait {
public function getBaseNamespace()
{
$reflection = new ReflectionClass(__CLASS__);
return $reflection->getNamespaceName().'\\';
}
}
The documentation says
The namespace keyword can be used to explicitly request an element from the current namespace or a sub-namespace. It is the namespace equivalent of the self operator for classes.
I need the equivalent of static instead, ie. if a class extends my class, the namespace of that.
This
return preg_replace('/.[^\\\\]+$/', '', get_class($object));
does it but it makes me sad.
Reflection provides an effective way of doing this via ReflectionObject->getNamespace(), check the following code:
namespace Foo {
class Bar {
public function getNamespace() {
return (new \ReflectionObject($this))->getNamespaceName();
}
}
}
namespace Baz {
use Foo\Bar as BaseClass;
class Bar extends BaseClass {}
}
namespace {
$bar1 = new Foo\Bar();
echo "ns1 is: ", $bar1->getNamespace(), '<br>';
$bar2 = new Baz\Bar();
echo "ns2 is: ", $bar2->getNamespace();
}
I don't think there's a "late static namespace" helper and you will indeed need to hack around.
e.g.
<?php
namespace ProjectFoo;
class Foo {
public static function ns() { echo __NAMESPACE__; }
public static function getNamespace() {
return static::ns();
}
}
namespace ProjectBar;
use ProjectFoo\Foo;
class Bar extends Foo {
public static function ns() { echo __NAMESPACE__; }
}
$foo = new Foo();
$foo::getNamespace();
print "\n";
$bar = new Bar();
$bar::getNamespace();
print "\n";