I have a problem which is probably not for most of you.
Sorry if it is obvious for you...
This is my code :
class Bat
{
public function test()
{
echo"ici";
exit();
}
public function test2()
{
$this->test();
}
}
In my controller:
bat::test2();
i have an error:
Exception information: Message: Method "test" does not exist and was
not trapped in __call()
Bat::test2 refers to a static function. So you have to declare it static.
class Bat
{
public static function test()
{
echo"ici";
exit();
}
// You can call me from outside using 'Bar::test2()'
public static function test2()
{
// Call the static function 'test' in our own class
// $this is not defined as we are not in an instance context, but in a class context
self::test();
}
}
Bat::test2();
Else, you need an instance of Bat and call the function on that instance:
$myBat = new Bat();
$myBat->test2();
Related
class MainClass {
public static function myStaticMethod(){
return myFunction();
function myFunction(){
echo 'hello';
}
}
}
The above code when executed returns call to undefined function myFunction();
Please, any ideas on how to call the function within the method?
Thank you
Move the function deceleration to before you attempt to use it when defining functions within other functions...
class MainClass
{
public static function myStaticMethod()
{
function myFunction()
{
echo 'hello';
}
return myFunction();
}
}
MainClass::myStaticMethod(); // No error thrown
Note that repeat calls to MainClass::myStaticMethod will raise Cannot redeclare myFunction() unless you manage that.
Otherwise, move it outside of your class
function myFunction()
{
echo 'hello';
}
class MainClass
{
public static function myStaticMethod()
{
return myFunction();
}
}
Take the following example of two classes:
class Yolo {
public function __invoke() {
echo 'YOLO';
}
}
class Swag {
public $yolo;
public function __construct() {
$this->yolo = new Yolo();
}
}
Is it possible to invoke the Yolo object via an instance of Swag?
(new Swag())->yolo(); throws a warning and doesn't call __invoke:
PHP Warning: Uncaught Error: Call to undefined method Swag::yolo()
In PHP 7 you can directly call it (just need extra braces):
((new Swag())->yolo)();
In PHP 5 you need a temp variable:
$y=(new Swag())->yolo;
$y();
The problem is that you try to call the function yolo() on the Swag class. In your case you have to use the public class variable and call the subclass over that.
var_dump((new Swag())->yolo);
that is your object. When you use () you try to call the class not the class variable.
You do not even have to make it a public method.
But you might have to reroute the call manually since the callable method is created at runtime:
class Yolo {
public function __invoke() {
echo 'YOLO';
}
}
class Swag {
private $yolo;
public function __construct() {
$this->yolo = new Yolo();
}
function __call($method, $args) {
if(is_callable($this->$method))
{
return call_user_func_array($this->$method, $args);
}
}
}
(new Swag())->yolo();
It would probably a good idea to check first, if the called method exists and if it is actually callable.
But the example works as a proof of concept.
Why does this return a "strict standard" notice?:
'Strict Standards: Non-static method main::i() should not be called statically in...'
class main
{
public function __construct()
{
echo "in main class";
}
public function i()
{
echo "i in main";
}
}
class secondary extends main
{
public static function tom()
{
parent::i();
}
}
secondary::tom();
I am legally calling a static method which contains a call to a non static method in a parent class.
The notice is telling you should not call a non static method within a static method.
You could check the method i(), if $this doesn't appear in that method, you may consider change i() to static method.
You've already answered the question yourself - while you're calling tom() statically (which is fine), i() is not static.
Being non-static i() assumes that you have an instance of the object, and therefore could be trying to access properties or perform other actions which require an instance. As such it shouldn't be called statically, not even from within a static method in a child class. Consider for example the following slight change to your code:
class main
{
var something = 0;
public function __construct()
{
echo "in main class";
}
public function i()
{
$this->something++;
echo "i in main";
}
}
class secondary extends main
{
public static function tom()
{
parent::i();
}
}
secondary::tom();
It's a strict warning - meaning you can choose to ignore it if you want to - but it's informing you that what you're doing is not generally good practice and you should probably rethink your approach.
class main
{
public function __construct()
{
echo "in main class";
}
public static function i()
{
echo "i in main";
}
}
class secondary extends main
{
public static function tom()
{
parent::i();
}
}
secondary::tom();
Is what it should look like, notice I have converted the function i(); to a static, which then can legally be called by parent::i();
But performing:
public static function tom()
{
$this->i();
}
Will return:
Fatal error: Using $this when not in object context
So your bet is to go fully static, or not static.
A resolution:
class main
{
public function __construct()
{
echo "in main class";
}
public function i()
{
echo "i in main";
}
}
class secondary extends main
{
public function tom()
{
$this->i();
}
}
$Class = new secondary();
$Class->tom();
I have a PHP class that looks like this:
class userAuthentication
{
public static function Authenticate()
{
if (isset($_COOKIE['email']))
{
verify($someVar, getPass($_COOKIE['email']);
}
}
public static function getPass($email)
{
}
public static function verify()
{
}
}
At times (I can't pin-point exactly when), I get a fatal error :
Call to undefined function getPass()
The error is thrown at the line where I call the function in the above code sample. Why is this happening when the function clearly exists.
It's a static function in a class. Use self::getPass() or static::getPass() if you want to take advantage of Late Static Binding. Same goes for verify().
verify is not a global function, but only valid in the scope of your class. You want
self::verify($someVar, getPass($_COOKIE['email']);
I would assume the error occurs when you try to run getPass($_COOKIE... since you're calling it wrong. Since the function is a class method, you have to run it like this:
$this->getPass(...);
or if you're calling it statically:
self::getPass(...);
Making your code:
class userAuthentication
{
public static function Authenticate()
{
if (isset($_COOKIE['email']))
{
self::verify($someVar, self::getPass($_COOKIE['email']);
// Or...
$this->verify($someVar, $this->getPass($_COOKIE['email']);
}
}
public static function getPass($email)
{
}
public static function verify()
{
}
}
You're not calling it as a static function.
From within the class use either:
self::getPass($email);
or (for late static binding):
static::getPass($email);
and from outside the class:
userAuthentication::getPass($email);
The line should probably be:
self::verify($someVar, self::getPass($_COOKIE['email']);
abstract class base {
abstract public function test();
public function run()
{
self::test();
}
}
class son extends base {
public function test()
{
echo 1;
}
}
son::run();
It reports:
Fatal error: Cannot call abstract
method base::test()
But son::test() works,why and is there a way to fix?
"self" is lexically scoped, that is, if you use "self" in a method of Base, "self" means "Base", no matter how you call this method at run time. php5.3 introduced a new kind of dynamic binding, which, ironically enough, is called "static". The following works as expected in php 5.3
abstract class base {
abstract public static function test();
static public function run()
{
static::test();
}
}
class son extends base {
static public function test()
{
echo 1;
}
}
son::run();
Of course:
Fatal error: Cannot call abstract method base::test()
It has no method body you could call. If run() is supposed to be a Template Method, you refer to the class scope with $this instead of self and then create an instance of $son to call run() on it, e.g.
abstract class BaseClass {
abstract public function test();
public function run()
{
$this->test();
}
}
class Son extends BaseClass {
public function test()
{
echo 1;
}
}
$son = new Son;
$son->run(); // 1
which is rather odd, because then you could have just as well called test() directly.
Also note that in your example
son::run();
is wrong, because the run() method is not declared static and while PHP will execute run() nonetheless, it is considered wrong usage and will raise an E_STRICT error. However, if you were to define run() static, you could no longer reference $this, because a static method is not invoked from instance scope, but class scope.
Edit I was about to add the PHP5.3 solution, but see that #erenon already did that, while I was typing, so I only add the appropriate reference in the PHP Manual on Late Static Binding.
Abstract methods do not have an implementation, and thus cannot be called. If the method is not defined as abstract, and actually has an implementation, then it can be executed by your code. For example:
public function test(){
echo "Hello from base!";
}
Factory/singleton pattern mix:
class Base
{
static private $instance;
static function getSon() {
if (null === self::$instance) {
self::$instance = new Son;();
}
return self::$instance;
}
}
class Son
{
public function test() {
echo 1;
}
}
Base::getSon()->test(); //1