I want to use an unknown class with a variable in another class:
Example
$classandmethod = "index#show";
namespace Lib\abc;
use Lib\xyz;
class abc{
function controller($classandmethod)
{
$a = explode("#", $classandmethod);
use Lib\Controller\.$a[0];
}
}
But maybe it's not true, please help everyone!
From the manual:
The use keyword must be declared in the outermost scope of a file (the global scope) or inside namespace declarations
So you can't use a class where you're trying to do it. Then, to instantiate a class from a different namespace from a variable, rather than useing it, supply the whole namespaced class:
<?php
namespace G4\Lib
{
class A
{
public $a = "test";
}
}
namespace G4
{
class B
{
public $a;
public function __construct($class)
{
$class = "\\G4\\Lib\\".$class;
$this->a = new $class; // here's the magic
}
}
$b = new B("A");
var_dump($b->a); // test
}
Demo
The main problem is that use cannot have a variable as part of it as it's used when parsing the file and the variable is only available at runtime.
This is an example of how you can do what you seem to be after...
<?php
namespace Controller;
ini_set('display_errors', 'On');
error_reporting(E_ALL);
class Index {
public function show() {
echo "Showing...";
}
}
$classandmethod = "Controller\Index#show";
list($className,$method) = explode("#", $classandmethod);
$a= new $className();
$a->$method();
This displays...
Showing...
You could of course say that all of these classes must be in the Controller namespace and so the code will change to
$classandmethod = "Index#show";
list($className,$method) = explode("#", $classandmethod);
$className = "Controller\\".$className;
$a= new $className();
$a->$method();
Related
I would like to be able to do something like this:
class ThingIDs
{
const Something = 1;
const AnotherThing = 2;
}
$thing = 'Something';
$id = ThingIDs::$thing;
This doesn't work. Is there a straightforward way of doing something equivalent? Note that I'm stuck with the class; it's in a library I can't rewrite. I'm writing code that takes arguments on the command line, and I would really like it to take symbolic names instead of id numbers.
Use the constant() function:
$id = constant("ThingIDs::$thing");
Use Reflection
$r = new ReflectionClass('ThingIDs');
$id = $r->getConstant($thing);
If you are using namespaces, you should include the namespace with the class.
echo constant('My\Application\ThingClass::ThingConstant');
Helper function
You can use a function like this:
function class_constant($class, $constant)
{
if ( ! is_string($class)) {
$class = get_class($class);
}
return constant($class . '::' . $constant);
}
It takes two arguments:
Class name or object instance
Class constant name
If an object instance is passed, its class name is inferred. If you use PHP 7, you can use ::class to pass appropriate class name without having to think about namespaces.
Examples
class MyClass
{
const MY_CONSTANT = 'value';
}
class_constant('MyClass', 'MY_CONSTANT'); # 'value'
class_constant(MyClass::class, 'MY_CONSTANT'); # 'value' (PHP 7 only)
$myInstance = new MyClass;
class_constant($myInstance, 'MY_CONSTANT'); # 'value'
<?php
class Dude {
const TEST = 'howdy';
}
function symbol_to_value($symbol, $class){
$refl = new ReflectionClass($class);
$enum = $refl->getConstants();
return isset($enum[$symbol])?$enum[$symbol]:false;
}
// print 'howdy'
echo symbol_to_value('TEST', 'Dude');
If you have a reference to the class itself then you can do the following:
if (defined(get_class($course). '::COURSES_PER_INSTANCE')) {
// class constant is defined
}
My problem was similiar to this subject. When you have the object, but not the class name, you could use:
$class_name = get_class($class_object);
$class_const = 'My_Constant';
$constant_value = constant($class_name.'::'.$class_const);
I know I'm a bit late, but I hope this can help anyway.
Based on Phil's answer, I created a default enumerator class that can be extended.
class DefaultEnum
{
static public function getConstantText(string $constant)
{
try {
// Get child class name that called this method
$child_class = get_called_class();
$reflection = new ReflectionClass($child_class);
$const = $reflection->getConstant($constant);
return $const;
} catch (\ReflectionException $e) {
// ...
}
}
}
class CustomEnum extends DefaultEnum
{
const something = 'abcd';
const something2 = 'ABCD';
}
You can call this method like this
CustomEnum::getConstantText('something');
It will return 'abcd'.
The function get_called_class() is a function that returns the class name that called this method and it works specifically for static methods.
In this case $child_class value will be CustomEnum::class. ReflectionClass accepts strings and object as parameter.
I would like to be able to do something like this:
class ThingIDs
{
const Something = 1;
const AnotherThing = 2;
}
$thing = 'Something';
$id = ThingIDs::$thing;
This doesn't work. Is there a straightforward way of doing something equivalent? Note that I'm stuck with the class; it's in a library I can't rewrite. I'm writing code that takes arguments on the command line, and I would really like it to take symbolic names instead of id numbers.
Use the constant() function:
$id = constant("ThingIDs::$thing");
Use Reflection
$r = new ReflectionClass('ThingIDs');
$id = $r->getConstant($thing);
If you are using namespaces, you should include the namespace with the class.
echo constant('My\Application\ThingClass::ThingConstant');
Helper function
You can use a function like this:
function class_constant($class, $constant)
{
if ( ! is_string($class)) {
$class = get_class($class);
}
return constant($class . '::' . $constant);
}
It takes two arguments:
Class name or object instance
Class constant name
If an object instance is passed, its class name is inferred. If you use PHP 7, you can use ::class to pass appropriate class name without having to think about namespaces.
Examples
class MyClass
{
const MY_CONSTANT = 'value';
}
class_constant('MyClass', 'MY_CONSTANT'); # 'value'
class_constant(MyClass::class, 'MY_CONSTANT'); # 'value' (PHP 7 only)
$myInstance = new MyClass;
class_constant($myInstance, 'MY_CONSTANT'); # 'value'
<?php
class Dude {
const TEST = 'howdy';
}
function symbol_to_value($symbol, $class){
$refl = new ReflectionClass($class);
$enum = $refl->getConstants();
return isset($enum[$symbol])?$enum[$symbol]:false;
}
// print 'howdy'
echo symbol_to_value('TEST', 'Dude');
If you have a reference to the class itself then you can do the following:
if (defined(get_class($course). '::COURSES_PER_INSTANCE')) {
// class constant is defined
}
My problem was similiar to this subject. When you have the object, but not the class name, you could use:
$class_name = get_class($class_object);
$class_const = 'My_Constant';
$constant_value = constant($class_name.'::'.$class_const);
I know I'm a bit late, but I hope this can help anyway.
Based on Phil's answer, I created a default enumerator class that can be extended.
class DefaultEnum
{
static public function getConstantText(string $constant)
{
try {
// Get child class name that called this method
$child_class = get_called_class();
$reflection = new ReflectionClass($child_class);
$const = $reflection->getConstant($constant);
return $const;
} catch (\ReflectionException $e) {
// ...
}
}
}
class CustomEnum extends DefaultEnum
{
const something = 'abcd';
const something2 = 'ABCD';
}
You can call this method like this
CustomEnum::getConstantText('something');
It will return 'abcd'.
The function get_called_class() is a function that returns the class name that called this method and it works specifically for static methods.
In this case $child_class value will be CustomEnum::class. ReflectionClass accepts strings and object as parameter.
I have a very simple question, but the answer might be rather complicated.
"How can I get the namespace of the block where a function call was made?"
So, when I do:
1. <?php
2. namespace TestTest;
3.
4. $myobj->doMethod();
How can $myobj->doMethod() know that the namespace on line 4. is TestTest?
This is only possible if the method is not called from the global scope. That's because there's no real way to backtrace it (please someone correct me here if that's not the case!). Simplest solution is to put your call in a function. It's likely you'll be using a method anyway if you're doing this sort of thing. If that's the case then you can use a combination of the debug_backtrace function and the reflection class:
file1.php:
<?php
namespace myns;
require 'file2.php';
function example($class) {
echo $class->nstest();
}
$class = new \myotherns\someclass();
echo example($class);
file2.php:
<?php
namespace myotherns;
class someclass {
function nstest() {
$backtrace = debug_backtrace();
$caller = end($backtrace);
$reflection = new \ReflectionFunction($caller['function']);
return $reflection->getNamespaceName();
}
}
Or all in one file:
<?php
namespace myns {
$someclass = new \myotherns\someclass();
echo example($someclass);
function example($class) {
echo $class->nstest();
}
}
namespace myotherns {
class someclass {
function nstest() {
$backtrace = debug_backtrace();
$caller = end($backtrace);
$reflection = new \ReflectionFunction($caller['function']);
return $reflection->getNamespaceName();
}
}
}
Here's an online demo
You'll need to tweak it depending on how you end up calling your method, but it should be simple enough.
I know there is a static class field on PHP 5.5, but I have to stick to PHP 5.4. Is it possible to get the fully qualified class name from a variable?
Example:
namespace My\Awesome\Namespace
class Foo {
}
And somewhere else in the code:
public function bar() {
$var = new \My\Awesome\Namespace\Foo();
// maybe there's something like this??
$fullClassName = get_qualified_classname($var);
// outputs 'My\Awesome\Namespace\Foo'
echo $fullClassName
}
You should be using get_class
If you are using namespaces this function will return the name of the class including the namespace, so watch out if your code does any checks for this.
namespace Shop;
<?php
class Foo
{
public function __construct()
{
echo "Foo";
}
}
//Different file
include('inc/Shop.class.php');
$test = new Shop\Foo();
echo get_class($test);//returns Shop\Foo
This is a direct copy paste example from here
I know this is an old question, but for people still finding this, I would suggest this approach:
namespace Foo;
class Bar
{
public static function fqcn()
{
return __CLASS__;
}
}
// Usage:
use Foo\Bar;
// ...
Bar::fqcn(); // Return a string of Foo\Bar
If using PHP 5.5, you can simply do this:
namespace Foo;
class Bar
{}
// Usage:
use Foo\Bar;
// ...
Bar::class; // Return a string of Foo\Bar
Hope this helps...
More info on ::class here.
For developers using PHP 8.0 and above, you can now easily do this without get_class.
PHP8 introduced the support for ::class on objects. Example:
public function bar() {
$var = new \My\Awesome\Namespace\Foo();
echo $var::class;
}
Here's the RFC for more info.
I would like to be able to do something like this:
class ThingIDs
{
const Something = 1;
const AnotherThing = 2;
}
$thing = 'Something';
$id = ThingIDs::$thing;
This doesn't work. Is there a straightforward way of doing something equivalent? Note that I'm stuck with the class; it's in a library I can't rewrite. I'm writing code that takes arguments on the command line, and I would really like it to take symbolic names instead of id numbers.
Use the constant() function:
$id = constant("ThingIDs::$thing");
Use Reflection
$r = new ReflectionClass('ThingIDs');
$id = $r->getConstant($thing);
If you are using namespaces, you should include the namespace with the class.
echo constant('My\Application\ThingClass::ThingConstant');
Helper function
You can use a function like this:
function class_constant($class, $constant)
{
if ( ! is_string($class)) {
$class = get_class($class);
}
return constant($class . '::' . $constant);
}
It takes two arguments:
Class name or object instance
Class constant name
If an object instance is passed, its class name is inferred. If you use PHP 7, you can use ::class to pass appropriate class name without having to think about namespaces.
Examples
class MyClass
{
const MY_CONSTANT = 'value';
}
class_constant('MyClass', 'MY_CONSTANT'); # 'value'
class_constant(MyClass::class, 'MY_CONSTANT'); # 'value' (PHP 7 only)
$myInstance = new MyClass;
class_constant($myInstance, 'MY_CONSTANT'); # 'value'
<?php
class Dude {
const TEST = 'howdy';
}
function symbol_to_value($symbol, $class){
$refl = new ReflectionClass($class);
$enum = $refl->getConstants();
return isset($enum[$symbol])?$enum[$symbol]:false;
}
// print 'howdy'
echo symbol_to_value('TEST', 'Dude');
If you have a reference to the class itself then you can do the following:
if (defined(get_class($course). '::COURSES_PER_INSTANCE')) {
// class constant is defined
}
My problem was similiar to this subject. When you have the object, but not the class name, you could use:
$class_name = get_class($class_object);
$class_const = 'My_Constant';
$constant_value = constant($class_name.'::'.$class_const);
I know I'm a bit late, but I hope this can help anyway.
Based on Phil's answer, I created a default enumerator class that can be extended.
class DefaultEnum
{
static public function getConstantText(string $constant)
{
try {
// Get child class name that called this method
$child_class = get_called_class();
$reflection = new ReflectionClass($child_class);
$const = $reflection->getConstant($constant);
return $const;
} catch (\ReflectionException $e) {
// ...
}
}
}
class CustomEnum extends DefaultEnum
{
const something = 'abcd';
const something2 = 'ABCD';
}
You can call this method like this
CustomEnum::getConstantText('something');
It will return 'abcd'.
The function get_called_class() is a function that returns the class name that called this method and it works specifically for static methods.
In this case $child_class value will be CustomEnum::class. ReflectionClass accepts strings and object as parameter.