Why function as array item in php class doesn't work - php

For example, I have such a code:
<?php
$A = array(
'echoSmth' => function(){
echo 'Smth';
}
);
$A['echoSmth'](); // 'Smth'
?>
It works fine!
But If $A is not just a variable, but a Class method - than this doesn't work:
<?php
class AA {
public $A = array(
'echoSmth' => function(){ // Parse Error here!
echo 'Smth';
}
);
}
// Fixed call:
$t = new AA();
$t->A['echoSmth']();
// no matter what call, because error occurs early - in describing of class
?>
Why doesn't it work?
It displays:
Parse error: syntax error, unexpected T_FUNCTION
P.S. Sorry, I've made some mistakes in the way I call the method, I was in hurry. But there's no matter how I call. Error ocurrs even if I just declare class, without calling

As far as I'm aware, you can't have anything dynamic when defining a class member, you can however set it dynamically as below. So basically, you can't do it for the same reason that you can't do this: public $A = functionname();
Also, your call signature was incorrect, I've fixed it in my example.
<?php
class AA {
public $A = array();
public function __construct() {
$a = function() {
echo 'Smth';
};
$this->A['echoSmth'] = $a;
}
}
$t = new AA();
$t->A['echoSmth']();
Alternatively, you could define the whole array within __construct(), containing the method (so basically shift your code).

I got this to work. Not sure why direct declaration is not permitted though.
class AA {
var $A;
public function __construct() {
$this->A = array(
'echoSmth' => function(){
echo 'Smth';
}
);
}
}
$t = new AA();
$t->A['echoSmth']();
EDIT: I also saw and corrected $t->$a first, but I needed to move the declaration as well to make it work.

well , it kinda works ...
<?php
class Bleh
{
public $f = array();
public function register( $name , $func )
{
$this->f[ $name ] = $func;
}
}
$foo = new Bleh;
$foo->register( 'bar' , function(){ echo 'foobar'; } );
$foo->f['bar']();
?>

Related

Call a method of an object whose name is stored in a variable - PHP

This question may sound stupid, but I want this to work. I've got this code:
$data['method'] = 'get';
$this->app->$data['method']();
How can I replace $data['method'] with get but no string. I've tried this, but no luck.
$this->app->{$data['method']}();
Any idea?
The last code you posted should work, if you're using PHP 5.4.0 and higher.
<?php
class A {
public function foo() {
echo "yes!";
}
}
class B {
public function run() {
$this->a = new A;
$data = [];
$data['method'] = "foo";
$this->a->{$data['method']}();
}
}
$b = new B;
$b->run();
// Prints "yes!"
This will work:
call_user_func(array($this->app, $data['method']));
good luck.

how to keep php Class method in a variable

1.here's my wrong code
class classname{
function __construct(){};
public function test(){return 0;};
}
$c = new classname();
$test = $c->test;
var_dump($test); //out put NULL, I want the method $c->test
I didn't want to execute the function and store the result
there is something wrong with my code.
howto write it!
here's the code what I wanted(by Bobot):
$test = function() use ($c) { return $c->test(); };
devmyb's answer was helpful,and he/she told me why my codes not works
Bobot 、JezEmery 、devmyb ... etc
thanks for your help
You're not calling the function, you're trying to access a property (which isn't found).
$test = $c->test();
That should work.
Your question is unclear, but I guess you want to do this :
$test = function() use ($c) { return $c->test(); };
Then when you need to run your method, just run the function : $test();
I guess that some documentation about anonymous functions can help you to understand the code.
Its because you didn't have your error_reporting on else you'll get the notice, warning and fatal error too
You have typographical errors, check the updated code
class classname{
function __construct(){} // removed ;
public function test(){return 0;} // removed ;
}
$c = new classname();
$test = $c->test; // You were calling variable of your class
$test1 = $c->test(); // You were calling method of your class i.e. public function test()
var_dump($test);
var_dump($test1);
Output:
Notice: Undefined property: classname::$test in /in/HBNf9 on line 9
NULL
int(0)
This is the correct code. After a function is no ;
class classname {
function __construct(){
}
public function test() {
return 0;
}
}
$c = new classname();
$test = $c->test;

Get line and file where object is created in PHP

Is it possible to get the line and file where a object is created?
For example.
I know the print PHP error outputs where a error occurred and at which line. Is it possible to use that mechanism?
Sending the file to the object is easy. I can just use basename(__FILE__) as an argument. But I would prefer if the object arguments can remain empty. Like this:
Foo.php
<?php
class Foo {
public $line = null;
public function __construct(){
$this->line = where_object_is_assigned
}
}
?>
Index.php
<?php
$object = new Foo();
echo $object->line // Output Index.php line 3
?>
Is there a way for the object to access this data without sending it?
Thanks in advance
I solved it by using the function debug_backtrace();
<?php
class Foo {
public $line = null;
public function __construct(){
$bt = debug_backtrace();
$caller = array_shift($bt); // Get first array
$this->line = $caller["line"];
}
}
?>
Index.php
<?php
$object = new Foo();
echo $object->line // Output: 3
?>
The function must be used in __construct() else it won't work.
Read more here: http://php.net/manual/en/function.debug-backtrace.php
This will output on which line-number the object is created
Class
class Foo {
public $line = NULL;
public function __construct($line){
$this->line = $line;
}
}
Index.php
<?php
$object = new Foo(__LINE__); //Will output 1
echo $object->line;
PHP provides a large number of predefined constants to any script which it runs. Within this you can simply find the predefined constant named as LINE
__LINE__ The current line number of the file.
So you need to simply use the predefined constant within your code like as
<?php
class Foo {
public $line = __LINE__;
}
$object = new Foo();
echo $object->line;
?>

Function literal in PHP class

Take a look at this code, please:
$array = array(
'action' => function () { echo "this works"; }
);
class Test {
public $array = array(
"action" => function () { echo "this doesn't"; }
);
}
The first function literal parses fine, but the second - the one inside the class - triggers a syntax error:
Parse error: syntax error, unexpected 'function' (T_FUNCTION)...
Can somebody explain this to me? Is this a bug?
EDIT: This is the latest PHP: 5.6.6
From the class it's a property !
Rule from properties :
Declaration may include an initialization, but this
initialization must be a constant value--that is, it must be able to
be evaluated at compile time and must not depend on run-time
information in order to be evaluated.
http://php.net/manual/en/language.oop5.properties.php
I dont have chance to test Your code on PHP 5.6.6, but I think this code resolve Your problem.
class Test{
public $array;
function __construct(){
$this -> array = array(
'action' => function (){
echo 'It works too';
}
);
}
}
$test = new Test();
$test -> array['action']();
Try it like this, let me know if this works for you
<?php
$array = array('action' => function () { echo "this works"; });
class Test {
public $arr;
function __construct() {
$this->arr = array("action" => function () { echo "this works too"; });
}
function getArr(){
var_dump($this->arr);
}
}
var_dump($array);
$obj = new Test();
$obj->getArr();

Reference to static method in PHP?

In PHP, I am able to use a normal function as a variable without problem, but I haven't figured out how to use a static method. Am I just missing the right syntax, or is this not possible?
(EDIT: the first suggested answer does not seem to work. I've extended my example to show the errors returned.)
function foo1($a,$b) { return $a/$b; }
class Bar
{
static function foo2($a,$b) { return $a/$b; }
public function UseReferences()
{
// WORKS FINE:
$fn = foo1;
print $fn(1,1);
// WORKS FINE:
print self::foo2(2,1);
print Bar::foo2(3,1);
// DOES NOT WORK ... error: Undefined class constant 'foo2'
//$fn = self::foo2;
//print $fn(4,1);
// DOES NOT WORK ... error: Call to undefined function self::foo2()
//$fn = 'self::foo2';
//print $fn(5,1);
// DOES NOT WORK ... error: Call to undefined function Bar::foo2()
//$fn = 'Bar::foo2';
//print $fn(5,1);
}
}
$x = new Bar();
$x->UseReferences();
(I am using PHP v5.2.6 -- does the answer change depending on version too?)
PHP handles callbacks as strings, not function pointers. The reason your first test works is because the PHP interpreter assumes foo1 as a string. If you have E_NOTICE level error enabled, you should see proof of that.
"Use of undefined constant foo1 - assumed 'foo1'"
You can't call static methods this way, unfortunately. The scope (class) is relevant so you need to use call_user_func instead.
<?php
function foo1($a,$b) { return $a/$b; }
class Bar
{
public static function foo2($a,$b) { return $a/$b; }
public function UseReferences()
{
$fn = 'foo1';
echo $fn(6,3);
$fn = array( 'self', 'foo2' );
print call_user_func( $fn, 6, 2 );
}
}
$b = new Bar;
$b->UseReferences();
In php 5.2, you can use a variable as the method name in a static call, but to use a variable as the class name, you'll have to use callbacks as described by BaileyP.
However, from php 5.3, you can use a variable as the class name in a static call. So:
class Bar
{
public static function foo2($a,$b) { return $a/$b; }
public function UseReferences()
{
$method = 'foo2';
print Bar::$method(6,2); // works in php 5.2.6
$class = 'Bar';
print $class::$method(6,2); // works in php 5.3
}
}
$b = new Bar;
$b->UseReferences();
?>
You could use the full name of static method, including the namespace.
<?php
function foo($method)
{
return $method('argument');
}
foo('YourClass::staticMethod');
foo('Namespace\YourClass::staticMethod');
The name array array('YourClass', 'staticMethod') is equal to it. But I think the string may be more clear for reading.
In PHP 5.3.0, you could also do the following:
<?php
class Foo {
static function Bar($a, $b) {
if ($a == $b)
return 0;
return ($a < $b) ? -1 : 1;
}
function RBar($a, $b) {
if ($a == $b)
return 0;
return ($a < $b) ? 1 : -1;
}
}
$vals = array(3,2,6,4,1);
$cmpFunc = array('Foo', 'Bar');
usort($vals, $cmpFunc);
// This would also work:
$fooInstance = new Foo();
$cmpFunc = array('fooInstance', 'RBar');
// Or
// $cmpFunc = array('fooInstance', 'Bar');
usort($vals, $cmpFunc);
?>
Coming from a javascript background and being spoiled by it, I just coded this:
function staticFunctionReference($name)
{
return function() use ($name)
{
$className = strstr($name, '::', true);
if (class_exists(__NAMESPACE__."\\$className")) $name = __NAMESPACE__."\\$name";
return call_user_func_array($name, func_get_args());
};
}
To use it:
$foo = staticFunctionReference('Foo::bar');
$foo('some', 'parameters');
It's a function that returns a function that calls the function you wanted to call. Sounds fancy but as you can see in practice it's piece of cake.
Works with namespaces and the returned function should work just like the static method - parameters work the same.
This seems to work for me:
<?php
class Foo{
static function Calc($x,$y){
return $x + $y;
}
public function Test(){
$z = self::Calc(3,4);
echo("z = ".$z);
}
}
$foo = new Foo();
$foo->Test();
?>
In addition to what was said you can also use PHP's reflection capabilities:
class Bar {
public static function foo($foo, $bar) {
return $foo . ' ' . $bar;
}
public function useReferences () {
$method = new ReflectionMethod($this, 'foo');
// Note NULL as the first argument for a static call
$result = $method->invoke(NULL, '123', 'xyz');
}
}
"A member or method declared with static can not be accessed with a variable that is an instance of the object and cannot be re-defined in an extending class"
(http://theserverpages.com/php/manual/en/language.oop5.static.php)

Categories