I have a function inside a function and the inner function cannot find the outer class. I don't know why. I hope someone has an idea how I can solve this. I don't want to declare the inner function outside of the outer function.
class Foo {
public $test = "test123";
private function outerfunction(){
function innerfunction(){
echo $this->test;
}
innerfunction();
}
}
if I call the inner function I get the error Using $this when not in object context.
just restructure it to an anonymous function:
$innerfunction = function () {
echo $this->test;
}
$innerfunction();
The class context is then automatically bound to the function (see also http://php.net/manual/en/functions.anonymous.php)
Be aware, that this only works for >= PHP 5.4
You have to declare it as a variable, or it will tell you that you aren't in an object context:
$innerfunction = function() {
echo $this->test;
};
call_user_func($innerfunction);
Alternatively, you can keep the function as you do, and pass it the object context since it's known at the call point:
function innerfunction(/* Foo */ $obj) {
echo $obj->test;
};
innerfunction($this);
The most glaring issue with this approach is that calling outerFunction() more than once will produce:
Fatal error: Cannot redeclare innerfunction()...
Another issue is that innerfunction() is declared in the global scope. If this is intentional then that is highly unconventional and you probably should not do that. Anyways, it allows for this:
class Foo {
public $test = "test123";
public function outerfunction(){
function innerfunction(){
//echo $this->test;
}
innerfunction();
}
}
$a = new foo();
// innerfunction(); // NOPE!
$a->outerFunction();
innerfunction(); // YES
So, this is the logical way to declare innerfunction():
class Foo {
public $test = "test123";
public function outerfunction(){
$this->innerfunction();
}
private function innerfunction(){
echo $this->test;
}
}
$a = new foo();
$a->outerFunction();
I'am trying to call a public funtion of a class with variables(php7). Therfore I do:
$module = 'frontend\\modules\\rest\\models\\Member';
$action = 'view_profile'
$response = new $module();
$response = $response1->$action;
By calling $response1->$action I get the following error:
Undefined property: frontend\modules\rest\models\Member::$view_profile
I see that the systems try to call ...Member\$view_profile and this will not work. But why is the '$' before view_profile. I've tried several variantes, but the error with the $view_profile is always there. What is wrong with this approach?
Check out this other reply: OOP in PHP: Class-function from a variable? (cannot comment, sorry...)
Anyway, this is what you are after: http://php.net/manual/en/functions.variable-functions.php
<?php
class Foo
{
function Variable()
{
$name = 'Bar';
$this->$name(); // This calls the Bar() method
}
function Bar()
{
echo "This is Bar";
}
}
$foo = new Foo();
$funcname = "Variable";
$foo->$funcname(); // This calls $foo->Variable()
?>
So I guess the only thing missing is the "()" after
$response1->$action;
After 9 hours of struggling to get this right, I have turned to the internet for help. I can't seem to find any relevant answers doing a Google search.
I currently have a class called Test. Test accepts a single argument.
<?php
class test {
private $varpassed;
public function getVarpas() {
return $this->varpassed;
}
Public function setVarpas($value) {
$this->varpassed= $value;
}
public function stringGen(){
$testvar = $this->varpassed;
echo $testvar;
}
}
The stringGen function should return the $varpassed variable whenever its called. The value for $varpassed is set using the setVarpas function. However, when ever I call the stringGen() method I only seem to be getting the following error:
Fatal error: Using $this when not in object context in file.php line 14.
Pointing to this line:
$testvar = $this->varpassed;
Is there any other way to pass the variable to the stringGen method? I've tried using:
self::$this->varpassed;
Which also throws an error.
first create an instance of the object (so you can use $this in the context), for example:
$test = new test();
then you can call:
$test->setVarpas('Hello World!');
now you can call:
$test->stringGen();
you have to do something like this
$var = new test();
$var->setVarpas("Hello");
$var->stringGen(); // this will echo Hello
$this is used when you are withing class. outside class you have to use class object.
1) Change this: class test() to class test
2) Create and instance first something like $t1 = new test();
3) Call the function $t1->setVarpas(5);
4) Now you can call the function $t1->stringGen();
Fixed:
<?php
class test
{
private $varpassed;
public function getVarpas() {
return $this->varpassed;
}
Public function setVarpas($value) {
$this->varpassed= $value;
}
public function stringGen(){
$testvar = $this->varpassed;
echo $testvar;
}
}
$t1 = new test();
$t1->setVarpas(5);
$t1->stringGen();
OUTPUT:
5
You should not declare a class with parentheses.
Use
class test {
instead of
class test(){
I'm trying to store anonymous functions in a static array property of my class. These functions should be invoked later by their index, but calling
self::$arr['index']()
just doesn't work, while
$a = self::$arr['index'];
$a();
does!
This doesn't work:
class A {
private static $func = array('a' => '');
public function __construct() {
self::$func['a'] = create_function('$str', 'echo "$str";');
}
public function go($str) {
self::$func['a']($str); // Call the function directly
}
}
$a = new A();
$a->go("hooray"); // Outputs "Undefined variable: func"
But this does:
class A {
private static $func = array('a' => '');
public function __construct() {
self::$func['a'] = create_function('$str', 'echo "$str";');
}
public function go($str) {
$a = self::$func['a']; // Pass the function name to a variable
$a($str); // Call the function via the variable
}
}
$a = new A();
$a->go("hooray"); // Outputs "hooray"
Why?
I'm using PHP Version 5.4.3
this is the behavior of php's parser
$functionName['a'] = "hello";
self::$functionName['a']();
calls
self::hello();
... the very sad thing is that in php you can't do this:
(self::$functionName['a'])(); // doesn't work in php :(
as you can do in javascript, for example
what you can do is... use a temporary variable like you said
$a = self::$func['a'];
$a($parameter);
or
call_user_func(self::$func['a'], $parameter);
hope this helps...
in latest phps these features were added
$a['sss'] = function(){ echo 'bla'; };
$a['sss']();
class Bla
{
private $a;
function test()
{
$this->a['sss'] = function(){ echo 'bla2'; };
$this->a['sss']();
}
}
$c = new Bla();
$c->test();
and they work properly... so for some reason, this syntax doesn't work only when using the scope resolution operator ( ClassName:: self:: etc)
Well, in php you simply can not do that, it is a php feature. But you can use call_user_func or its relatives:
return call_user_func(self::$func['$a'], $str);
This is a consequence of how the PHP parser currently works. Since the function call () is evaluated before the static operator ::, you end up with the parser attempting to reference the local variable $func instead, and then giving you the error about $func being undefined (which it is, since there is no variable named $func in the method).
As you've discovered, you can solve this by doing two separate statements.
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)