PHP class name as a string - php

Is there a built-in static method or property to refer to a PHP class so that it will contextually be represented as a string? For example:
Instead of this:
$obj->tempFn('MyClass') //MyClass being the name of the class
I want to do this:
$obj->tempFn(MyClass) //Directly references the class name, instead of a string representation

No. But you can define a constant in your class, that contains the class name, like:
class foo{
const
NAME = 'foo';
}
And access it like foo::NAME.
In PHP 5.5, you'll be able to use:
foo::class

echo get_class($this);should work inside of a class.
echo __CLASS__; I believe this is a static property

If really wanting to avoid the statics I think the Reflection class might work.
function getClassName(ReflectionParameter $param) {
preg_match('/\[\s\<\w+?>\s([\w]+)/s', $param->__toString(), $matches);
return isset($matches[1]) ? $matches[1] : null;
}
That's from the comments on http://www.php.net/manual/en/reflectionparameter.getclass.php

Related

PHP: Problems Instantiating Class

I try to create new object of a class called Isolate (this class is used to prevent XSS and other attacks via htmlspecialchars and so on).
So, I do it like this:
$data['name'] = $_POST['name'];
$data = $isolate->isolateArr($data);
And my Isolate class look like this:
class Isolate {
public function isolate($var) {
$iVar = htmlspecialchars($var);
$iVar = mysql_real_escape_string($iVar);
$iVar = stripcslashes($iVar);
return $iVar;
}
public function isolateArr($arr) {
foreach($arr as &$instance) {
$instance = $this->isolate($instance);
}
unset($instance);
return $arr;
}
But as the result I have a warning like Missing argument 1 for Isolate. As I understand, it asks me for the argument for the first function, but I do not need to call the first one, I need to call the second (because I have an array in this case).
So, why does it always ask for the first function argument? There in no any __construct method, what is the point?
Thank you in advance!
isolate() is your constructor method.
http://www.php.net/manual/en/language.oop5.decon.php
For backwards compatibility, if PHP 5 cannot find a __construct() function for a given class, and the class did not inherit one from a parent class, it will search for the old-style constructor function, by the name of the class.

Using class name from a static constant statically in PHP

I have the class name Car stored as a static variable in constants. I would like to use this constant to call the function a. One options is to use an intermediate variable $tmp. I could then call $tmp::a(). Is there a way to do this in one statement? My attempt is below.
class Car{
public static function a(){
return 'hi';
}
}
class Constants{
public static $use='Car';
}
$tmp=Constants::$use;
echo(${Constants::$use}::a());
IDEOne link
Output is as follows
PHP Notice: Undefined variable: Car in /home/mU9w5e/prog.php on line 15
PHP Fatal error: Class name must be a valid object or a string in /home/mU9w5e/prog.php on line 15
There is always call_user_func():
echo call_user_func( array( Constants::$use, 'a'));
IDEOne Demo
The only alternative that I could find to #nickb's way was using something I've never heard of, but hey that's what SO is for!
I found the ReflectionMethod, which seems to be more bloated than the call_user_func, but was the only alternative way that I could find:
<?php
class Car{
public static function a(){
return 'hi';
}
}
class Constants{
public static $use='Car';
}
$reflectionMethod = new ReflectionMethod(Constants::$use, 'a');
echo $reflectionMethod->invoke(new Car());
The above is a bit of a failed experiment as Casebash doesn't want to create temp variables.
As CORRUPT mentioned in the comments, it is possible to use the following although was tested on PHP version 5.4.14 (which I am unable to do):
echo (new ReflectionMethod(Constants::$use, 'a'))->invoke(new Car());
I have crazy solution, but you should never use it :^ )
echo ${${Constants::$use} = Constants::$use}::a();

Access class constant and static method from string

I have a string containing the class name and I wish to get a constant and call a (static) method from that class.
<?php
$myclass = 'b'; // My class I wish to use
$x = new x($myclass); // Create an instance of x
$response = $x->runMethod(); // Call "runMethod" which calls my desired method
// This is my class I use to access the other classes
class x {
private $myclass = NULL;
public function __construct ( $myclass ) {
if(is_string($myclass)) {
// Assuming the input has a valid class name
$this->myclass = $myclass;
}
}
public function runMethod() {
// Get the selected constant here
print $this->myclass::CONSTANT;
// Call the selected method here
return $this->myclass::method('input string');
}
}
// These are my class(es) I want to access
abstract class a {
const CONSTANT = 'this is my constant';
public static function method ( $str ) {
return $str;
}
}
class b extends a {
const CONSTANT = 'this is my new constant';
public static function method ( $str ) {
return 'this is my method, and this is my string: '. $str;
}
}
?>
As I expected (more or less), using $variable::CONSTANT or $variable::method(); doesn't work.
Before asking what I have tried; I've tried so many things I basically forgot.
What's the best approach to do this? Thanks in advance.
To access the constant, use constant():
constant( $this->myClass.'::CONSTANT' );
Be advised: If you are working with namespaces, you need to specifically add your namespace to the string even if you call constant() from the same namespace!
For the call, you'll have to use call_user_func():
call_user_func( array( $this->myclass, 'method' ) );
However: this is all not very efficient, so you might want to take another look at your object hierarchy design. There might be a better way to achieve the desired result, using inheritance etc.
in php 7 you can use this code
echo 'my class name'::$b;
or
#Uncomment this lines if you're the input($className and $constName) is safe.
$reg = '/^[a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*$/';
if(preg_match($reg,$className) !== 1 || preg_match($reg,$constName) !== 1)
throw new \Exception('Oh, is it an attack?');
$value = eval("return $className::$constName;");
You can achieve it by setting a temporary variable. Not the most elegant way but it works.
public function runMethod() {
// Temporary variable
$myclass = $this->myclass;
// Get the selected constant here
print $myclass::CONSTANT;
// Call the selected method here
return $myclass::method('input string');
}
I guess it's to do with the ambiguity of the ::, at least that what the error message is hinting at (PHP Parse error: syntax error, unexpected T_PAAMAYIM_NEKUDOTAYIM)
Use call_user_func to call static method:
call_user_func(array($className, $methodName), $parameter);
Classes defined as abstract may not be instantiated, and any class that contains at least one abstract method must also be abstract. Methods defined as abstract simply declare the method's signature - they cannot define the implementation.
When inheriting from an abstract class, all methods marked abstract in the parent's class declaration must be defined by the child; additionally, these methods must be defined with the same (or a less restricted) visibility. For example, if the abstract method is defined as protected, the function implementation must be defined as either protected or public, but not private. Furthermore the signatures of the methods must match, i.e. the type hints and the number of required arguments must be the same. This also applies to constructors as of PHP 5.4. Before 5.4 constructor signatures could differ.
Refer to http://php.net/manual/en/language.oop5.abstract.php
This might just be tangential to the subject but, while searching for my own issue I found that the accepted answer pointed me in the right direction, so I wanted to share my problem & solution in case someone else might be stuck in a similar fashion.
I was using the PDO class and was building some error options from an ini config file. I needed them in an associative array in the form: PDO::OPTION_KEY => PDO::OPTION_VALUE, but it was of course failing because I was trying to build the array with just PDO::$key => PDO::$value.
The solution (inspired from the accepted answer):
$config['options'] += [constant('PDO::'.$key) => constant('PDO::'.$option)];
where everything works if you concatenate the class name and the Scope Resolution Operator as a string with the variable and get the constant value of the resulting string through the constant function (more here).
Thank you and I hope this helps someone else!

PHP: Calling a class name using an inherited function from a extended class

If effect, I have this in progress:
Class Foo {
$bar = new Bar();
protected function Spoon() {
get_class($this);
}
}
Class Bar extended Foo {
$this::Spoon(); //Should show "Bar", but instead shows "Foo"
}
I want to be able to find "Bar" from Spoon(), but I always get the parent class.
I'm a little lost here. How might I get this code to work properly?
get_class() returns 'Foo', because since the Spoon() method is inherited, it's executed in the Foo class.
Using the __CLASS__ constant instead of get_class() should work as you want it to.
you can either use the late static binding (php >= 5.3) like in this answer.
protected function Spoon() {
get_called_class($this);
}
or call the function with
$this->Spoon();
Try:
echo parent::Spoon();
That will force it to referenced in the context of the parent class (Foo). You could also use get_parent_class() inside Bar:
echo get_parent_class('Bar');

instanceof equivalent for a string-represented classname

I'm looking for a functionality, in the example below called "theFunctionILookFor", that will make the code work.
$myClassName = "someName";
$parentOrInterfaceName = "someParent";
if (theFunctionILookFor($myClassName)) {
echo "is parent";
}
Edit: I try to avoid instantiating the class just to perform this check. I would like to be able to pass 2 string parameters to the checking function
Looks like this is my answer: is_subclass_of
It can accept both parameters as strings
http://php.net/manual/en/function.is-subclass-of.php
Try is_subclass_of(). It can accept both parameters as strings. http://php.net/manual/en/function.is-subclass-of.php
Using the Reflection API, you can construct a ReflectionClass object using the name of the class as well as an object.
You might use this?
http://www.php.net/manual/en/function.get-parent-class.php
From the page:
get_parent_class
(PHP 4, PHP 5, PHP 7)
get_parent_class — Retrieves the parent class
name for object or class
Description
string get_parent_class ([ mixed $object ] )
Retrieves the parent
class name for object or class.
This is an old thread, but still for future reference, you can use the functions is_a and is_subclass_of to accomplish this in a more efficient way.
No need to instantiate anything, you can just pass your string like:
if (is_subclass_of($myObject, 'SomeClass')) // is_a(...)
echo "yes, \$myObject is a subclass of SomeClass\n";
else
echo "no, \$myObject is not a subclass of SomeClass\n";
PHP Docs:
http://www.php.net/manual/en/function.is-a.php
http://www.php.net/manual/en/function.is-subclass-of.php
I think that instanceof is a lot faster and more clear to read.
instanceof does not work on strings, because it can be used as a "identifier" for a class:
$temp = 'tester';
$object = new sub();
var_dump($object instanceof $temp); //prints "true" on php 5.3.8
class tester{}
class sub extends \tester{
}
Also, it works on interfaces - you just need a variable to contain the absolute class name (including namespace, if you want to be 100% sure).
Maybe it's old question, but problem still is actual, here, below, the best solution I've found
class ProductAttributeCaster
{
public function cast(mixed $value): mixed
{
if ($value instanceof ($this->castTo())) {
// do stuff
}
return $value;
}
function castTo(): string
{
return ProductAttribute::class;
}
}

Categories