Something is wrong with class_alias - PHP - php

I'm trying to use class_alias on a facade \Facades\Security.
I tried this:
class_alias("\\Facades\\Security", "Security");
echo Security::Unique();
But i got an error (Class 'Security' not found in...).
The weird thing is that when i try this:
$facade = "Security";
class_alias("\\Facades\\" . $facade, $facade);
echo $facade::Unique();
It does work and i get an output from the function 'Unique'.
So somehow storing the name of the facade in a variable and accessing it from there, fixes the problem...
Can someone tell me why?
Thanks :)

Suppose you are using namespace of class name.., so no need escape (\), try this code
class_alias("\Facades\Security", "Security");
echo Security::Unique();
Update
You will also need to add namespace in alias class B, see sample code
<?php
namespace Facades;
class Security {
public static function Unique(){
return "Test return";
}
}
class_alias("\Facades\Security", "\Facades\B");
echo B::Unique();
?>
DEMO

Related

Is it possible to get the list of the class alias in php as array?

example
namespace Foo;
use Test\One;
use Test\Two;
use Test\Three;
class Sample
{}
How can I get the aliases (USE) as an array?
example of what I am looking to get
$test = [Test\One, Test\Two, Test\Tree];
Does anybody have any suggestions without scanning the file?
or is there a PHP function that will return the list aliases as an array?
Any help will be very appreciated.
Assuming I have the following class and the file is located and named as following file name and location src/Foo.php
namespace Foo;
use Test\One;
use Test\Two;
use Test\Three;
class Sample
{}
now I can scan this file
with this function, I can scan that class and get the result expected.
<?php
use \SplFileObject;
class Scanner
{
public static function getUseAliases()
{
$className = new SplFileObject("src/Foo.php");
$use = [];
while (!$className->eof())
{
$alias = explode("use ", $className->fgets());
if(!empty($alias[1]))
{
$use[] = trim($alias[1]);
}
}
$className = null; //Unset the file to prevent memory leaks
print_r($use);//will print my expected output [Test\One, Test\Two, Test\Three]
}
}
I think there should be a better way to get the same results and this is why I posted my current solution. Please let me know your thoughts.
You can try to use this class:
https://gist.github.com/Zeronights/7b7d90fcf8d4daf9db0c

Fully qualified interface name

Is there a way to get fully qualified interface name similar to MyClass::class?
For example:
namespace Example\Tests;
use Example\Interfaces\InputInterface;
...
class CommandTest ...
...
public function createInputMock()
{
// I want to replace next string with something similar to MyClass::class
$this->getMockBuilder('Example\Interfaces\InputInterface')
...
Thank you.
The ::class name resolution can work with any imported namespaces: classes, interfaces, functions, ...
namespace A\B\C {
interface Interface_Bar {}
function Function_Foo() {}
function Function_Foo_Bar() {}
const Const_BARFOO = 123;
}
namespace {
use A\B\C\Interface_Bar;
use A\B\C;
use Undefined\Classes\UndefinedClass;
use function A\B\C\Function_Foo_Bar;
use const A\B\C\Const_BARFOO;
echo Interface_Bar::class, "\n"; // print A\B\C\Interface_Bar
echo C\Function_Foo::class, "\n"; // print A\B\C\Function_Foo
echo C\Const_BARFOO::class, "\n"; // print A\B\C\Const_BARFOO
echo UndefinedClass::class, "\n"; // print Undefined\Classes\UndefinedClass
echo Function_Foo_Bar::class, "\n"; // print Function_Foo_Bar <- warning
echo Const_BARFOO::class, "\n"; // print Const_BARFOO <- warning
}
If I got you right, you can't move to PHP 5.5 with ::class notation, so you want to have something similar in your 5.4 or earlier vesrion.
So the short answer is — no, there is no way.
The lack of this functionality in the previous versions of PHP is what made core developers to add ::class to PHP 5.5.
You can make a weird dirty hack if it's a class name: using get_class on new instance, but don't do it.

In PHP, can you DEFINE a constant that can be used in function names?

In Drupal, there are many functions that are hook_functionname1, hook_functionname2. When writing a module, you have to replace the text 'hook' with your module name, so Drupal loads your module "my_drupal_module" and runs hooks like "my_drupal_module_functionname1" and "my_drupal_module_functionname2".
Is it possible in PHP to use DEFINE to simply define the word "hook" and set it to a string? If it is possible, then you should be able to copy and paste word-for-word hook_anything and not have to change it. And, if you ever wanted to change the name of your module, you would merely change the single constant, rather than find/replace all the function names.
So can you use DEFINE or some other setting to meta-program in PHP?
You want something like:
$moduleFunctionName = 'hook';
$functionNameOne = $moduleFunctionName . '_functionname1';
$functionNameTwo = $moduleFunctionName . '_functionname2';
$functionNameOne = function($var) {
// blah
}
..//
Function $functionNameOne is defined through anonymous function. It becames available in php from php 5.3.0
Maybe you want something like this
<?
define('PREFIX', 'myprefix');
//like this time you deside that this will me the second part
$somevar = '_this_function_name';
// now we combine prefix and name
$function_name = PREFIX . $somevar;
// now we check if we can run this function
if(!function_exists($function_name)){
echo "no function $funcion_name exist";
}
else{
$function_name();
}
function myprefix_this_function_name(){
echo 'running function';
}
?>
this will output
running function
This actually works:
define('FN_NAMESPACE', 'hook_');
${FN_NAMESPACE . 'functionNameOne'} = function($var) {
echo "Hi, I got $var\n";
};
$hook_functionNameOne('test');
Will output
Hi, I got test

Dynamic static method call in PHP?

Please could someone experienced in PHP help out with the following. Somewhere in my code, I have a call to a public static method inside a non-instantiated class:
$result = myClassName::myFunctionName();
However, I would like to have many such classes and determine the correct class name on the fly according to the user's language. In other words, I have:
$language = 'EN';
... and I need to do something like:
$result = myClassName_EN::myFunctionName();
I know I could pass the language as a parameter to the function and deal with it inside just one common class but for various reasons, I would prefer a different solution.
Does this make any sense, anyone? Thanks.
Use the call_user_func function:
http://php.net/manual/en/function.call-user-func.php
Example:
call_user_func('myClassName_' . $language . '::myFunctionName');
I think you could do:
$classname = 'myClassName_' . $language;
$result = $classname::myFunctionName();
This is called Variable Functions
I would encapsulate the creation of the class you need in a factory.
This way you will have a single entry point when you need to change your base name or the rules for mapping the language to the right class.
class YourClassFactory {
private $_language;
private $_basename = 'yourclass';
public YourClassFactory($language) {
$this->_language = $language;
}
public function getYourClass() {
return $this->_basename . '_' . $this->_language;
}
}
and then, when you have to use it:
$yourClass = $yourClassFactoryInstance->getYourClass();
$yourClass::myFunctionName();
As temuri said, parse error is produced, when trying '$className::functionName' :
Parse error: syntax error, unexpected T_PAAMAYIM_NEKUDOTAYIM ...
In my case (static method with 2 arguments), best solutions is to use call_user_func_array with 2 arrays (as suggested by nikc.org):
$result = call_user_func_array(array($className, $methodName), array($ard1, $arg2));
BR
although i think the way you deal is a very bad idea, i think i may have a solution
$className = 'myClassName_'.$language;
$result = $className::myFunctionName();
i think this is what you want
You can easily do next:
<?php
class B {
public static $t = 5;
public static function t($h) {
return "Works!" . $h;
}
}
$g = 't';
$class = 'B';
echo $class::$g('yes'); //Works! Yes
And it will works fine, tested on PHP 5.2 >=
As far as i could understand your question, you need to get the class name which can be done using get_class function. On the other hand, the Reflection class can help you here which is great when it comes to methods, arguments, etc in OOP way.
Solutions like:
$yourClass::myFunctionName();
will not work. PHP will produce parse error.
Unfortunately, the only way is to use very slow call_user_func().
I know it's an old thread, but as of PHP 5.3.0 you should be using forward_static_call
$result = forward_static_call(array('myClassName_EN', 'myFunctionName'));
Using your $language variable, it might look like:
$result = forward_static_call(array('myClassName_' . $language, 'myFunctionName'));

Extended class not found when Base class is in a separate include file

This doesn't work:
test.php:
include_once('test-include.php');
$main = new mainClass();
//======================================================================
class mainClass {
function __construct() {
$test2 = new Test2();
echo $test2->var;
}
}
//======================================================================
class Test2 extends Test1 { // test2
var $var = 'b';
}
test-include.php:
// this does get printed out, so I know the include statement is working
echo 'DEBUG: this is the test-include.php file<br>';
//======================================================================
class Test1 { // test1
var $var = 'a';
}
It gives the following error
PHP Fatal error: Class 'Test2' not found in /path/to/test.php on line 8
whereas this does work
test2.php:
// this is in the same position as the include statement in test.php
//======================================================================
class Test1 { // test1
var $var = 'a';
}
$main = new mainClass();
//======================================================================
class mainClass {
function __construct() {
$test2 = new Test2();
echo $test2->var;
}
}
//======================================================================
class Test2 extends Test1 { // test2
var $var = 'b';
}
Why does putting the Base class (Test1) in an include file cause the child class that is extending it to not be found? In other words, the first example is failing because it can't find Test2 when we attempt to instantiate it. This kind of makes sense as we haven't gotten to Test2 in the code execution flow yet. However, in the second example (without the include statement) there's no error, even though it's a similar situation (we haven't reached the Test2 class in code execution yet)
Oh, and this is under version 5.1.6.
UPDATE:
OK, Daff is correct - if I move
$main = new mainClass();
to the end in the test.php example, it works. I would still like to know why it doesn't work if the above line isn't at the end - it works just fine in the test2.php example which doesn't have the $main = new mainClass() line at the end.
UPDATE 2:
OK, I've tried using require, require_once and include in place of include_once - none of these work. And I also added a test echo statement to the test-include.php file and it gets printed out (plus I don't get an error about a non-existent include file) so I know the include statement is working.
This should have something to do with the definition order and that EVERY class should be included before you actually work with them. If you put the call of
$main = new mainClass();
At the end of your script it works fine even with the include file because all the classes are defined already. Eventually you should have a look at the PHP autoload function because you will get rid of these problem with one small function.
OK, I think I may have figured this one out. According to this bug report:
http://bugs.php.net/bug.php?id=30453
PHP 4 allowed classes to be defined after they are used but for PHP 5, in the words of the end poster on the bug thread:
PHP5 supports it [declaring classes
after they are used] for backward
compatibility, but we don't plan
support for all combinations.
So I'm guessing this particular case is one of those unsupported combinations.

Categories