I have a woocommerce plugin that has a class Foo:
function wc_foo_init(){
class WC_Foo extends WC_Shipping_Method{
$var=get_option(); //gets an option for this session
function sayHello(){
echo $var;
}
new WC_Foo();
}
I want to call sayHello() out of the Foo class:
function bar(){
WC_Foo->sayHello();
}
But I get this error:
Fatal error: Call to a member function `sayHello` on a non-object.
You must instantiate class before make call of its methods:
$foo = new WC_Foo();
$foo->sayHello();
or if your php version is greater than 5.4 you can do:
(new WC_Foo())->sayHello();
Use $this selector if you are calling the method within the class
function bar(){
$this->sayHello();
}
If you want to call the method from other place,
you need to instantiate the class like this:
$object = new WC_Foo();
$object->sayHello();
Or make the method static like this:
public static function sayHello(){
echo "Hello";
}
And call it like this:
WC_Foo::sayHello();
// this way you dont need $object = new WC_Foo();
This might not be the full code, so it's pretty weird what you have there, but let's go.
Since you have a function to init your object, you would probably want to at least return that instance. This code might help you understand:
function init_foo(){
class foo{
function say(){
echo 'hello';
}
}
$foo1 = new Foo();
return $foo1;
}
function bar($foo3){
$foo3->say();
}
$foo2 = init_foo();
bar($foo2);
So, first we create the object and return it. Then we inject it in the bar function, just needing to call the method after that. (I used different var names so it's easier to understand scope)
Related
class MyClass {
var $lambda;
function __construct() {
$this->lambda = function() {echo 'hello world';};
// no errors here, so I assume that this is legal
}
}
$myInstance = new MyClass();
$myInstance->lambda();
//Fatal error: Call to undefined method MyClass::lambda()
So what is the correct syntax for reaching class variables ?
In PHP, methods and properties are in a separate namespace (you can have a method and a property with the same name), and whether you are accessing a property or a method depends of the syntax you are using to do so.
$expr->something() is a method call, so PHP will search something in the class' list of methods.
$expr->something is a property fetch, so PHP will search something in the class' list of properties.
$myInstance->lambda(); is parsed as a method call, so PHP searches for a method named lambda in your class, but there is no such method (hence the Call to undefined method error).
So you have to use the fetch property syntax to fetch the lambda, and then call it.
Since PHP 7.0, you can do this with ($obj->lambda)():
($obj->lambda)();
The parentheses make sure that PHP parses ($obj->lambda) as fetch the property named lambda. Then, () calls the result of fetching the property.
or you can do this with ->lambda->__invoke():
$myInstance = new MyClass();
$myInstance->lambda->__invoke();
__invoke is one of PHP's magic methods. When an object implements this method, it becomes invokable: it can be called using the $var() syntax. Anonymous functions are instances of Closure, which implements __invoke.
Or assign it to a local variable:
$lambda = $myInstance->lambda;
$lambda();
Or call it using call_user_func:
call_user_func($myInstance->lambda);
call_user_func can call any callable, including anonymous functions.
Alternatively, if this is a common pattern in your code, you can setup a __call method to forward calls to your lambda:
class MyClass
{
private $lambda;
public function __construct()
{
$this->lambda = function() {
echo "Hello world!\n";
};
}
public function __call($name, $args)
{
return call_user_func_array($this->$name, $args);
}
}
Now this works:
$myInstance = new MyClass();
$myInstance->lambda();
Since PHP 5.4 you can even do that in a trait:
trait LambdasAsMethods
{
public function __call($name, $args)
{
return call_user_func_array($this->$name, $args);
}
}
class MyClass
{
use LambdasAsMethods;
private $lambda;
public function __construct()
{
$this->lambda = function() {
echo "Hello World!\n";
};
}
}
$myInstance = new MyClass();
$myInstance->lambda();
You can also call your lambda function without change something in your class, using ReflectionFunction.
$myInstance = new MyClass();
$lambda = new ReflectionFunction($myInstance->lambda);
$lambda->invoke();
or if you have to pass arguments then
$args = array('arg'=>'value');
$lambda->invokeArgs($args);
I have a class setup like this:
class myClass {
public function __construct() {
echo 'foo bar';
}
}
To run it, I can simply do:
$object = new myClass;
Is there any way to run the class so __construct initiates without creating a new variable with the class object.
For example, a basic function can be run with:
functionname();
Don't call __construct directly. If you need something in the constructor to occur but you don't want an object created as a result, then use a static method.
class Thing{
public static function talk(){echo "I talk";}
}
Thing::talk(); // 'I talk'
Static methods can be called without the need for an object instance of the class.
__construct is part of a special group of methods in PHP, called Magic Methods. You don't call these directly, but PHP will call them when some event occurs. For instance when you call new on a class, __construct is executed.
Another example: if you try to get a property that doesn't exist, __get will be executed (if found):
Class Thing{
public property $name = 'Berry';
public function __get($propertyName){
return "$propertyName does not exist!";
}
}
$t = new Thing();
echo $t->name; // 'Berry'
echo $t->weight; // 'weight does not exist!';
You can try something like this if you want to avoid static:
(new MyClass)->myFunction();
I have no idea why you need this but you don't need to create a variable. You can just create object without store it anywhere.
class myClass {
public function __construct() {
echo 'foo bar';
}
}
new myClass();
In this case only the constructor will be call.
I have problem, can i call constructor without create 'new class()' ? Or you maybe have another way for this :
<?php
class a
{
public static $hello;
public function say()
{
return self::$hello;
}
}
class b extends a
{
public function __construct()
{
self::$hello = 'hello world';
}
}
echo b::say();
?>
I have try with :
$b = new b();
echo $b->say();
And it's work. But i want to use b::say();
Can help me?
Thank you!!
Check out this. Is this good for you?
<?php
class a {
public static $hello;
public static function say() {
return self::$hello;
}
}
class b extends a {
public function __construct() {
self::$hello = 'hello world';
}
public static function factory() {
return new b();
}
}
echo b::factory()->say();
?>
Actually I couldn't find a way to do this without calling constructor. This is how the workaround looks like. factory is just a name. you can rename it.
calling class method (with constructors) without object instantiation in php
You have asked: "can i call constructor without create 'new class()' ?"The answer: No.
... Classes which have a constructor method call this method on each
newly-created object
You have requested "But i want to use b::say();"
b::say(); - is call of static method.You can't override non-static parent method to static. But you can restructure your base class class a to make say() method static.
<?php
class a
{
public static $hello;
public static function say()
{
return self::$hello;
}
}
class b extends a
{
public function __construct()
{
self::$hello = 'hello world';
}
}
The thing that you were missing was you needed to add your content to your new class method. - Just call it like so:
$b = new b('Some words');
echo $b->say();
When calling a new class and using a constructor - You will want to add the content in the paramaters for the new class you are making.
It acts as if you are calling the __construct function. - Calling new class($a) will call the __construct($a) function once making the object.
Hope that this helped a bit :)
Yes it is possible just make the say() function static like this :
public static function say()
{
return self::$hello;
}
Declaring class methods as static makes them accessible without needing an instantiation of the class.
This example looks to me like late static binding. So try changing that return self::$hello; into return static::$hello;
I saw some codes that when they call php functions from another class they no longer use $this->functionName(),
they just refer immedietly to the function name, like functionName()
In my index.php
$help = new Helper();
$help->Test();
I wanted to call Test Function by not doing the $help.
How can this be done? Why is this possible?
In PHP you can mix a procedural style of programming with object oriented style. That means that function can either exist as member of a class, or as stand-alone functions.
Member functions (or methods) are are called using $classinstance->methodname() for normal (instance) methods, or ClassName::methodName() for static methods.
Standalone functions are just called without referring to a class or object whatsoever. You can put them in separate files, if you like.
The declaration and usage is as follows:
In example.php:
class MyClass
{
$member = 'Hello world';
function MyMethod()
{
// The method can use the instance variable (member variable)
// using $this to refer to the instance of the class
echo $this->member;
}
static function MyStaticMethod()
{
echo 'Hello static world';
}
}
function MyFunction()
{
echo 'Hello';
}
In index.php:
// To include the class and its methods, as well as the function.
require_once 'example.php';
// Call an instance method
$instance = new MyClass();
$instance->MyMethod();
// Call a static method
MyClass::MyStaticMethod();
// Call a stand-alone function
MyFunction();
A standalone function is defined like this:
function myfunction() {
# whatever
}
Also see http://www.php.net/manual/en/functions.user-defined.php
With the -> operator you reference a function from within a class.
<?php
class A {
public function a() {
$this->b(); //references the function b() in $this class
}
public function b() {
echo 'Was called from function a() in class A';
}
}
function c() {
echo "I'm just a simple function outside a class";
}
//now you can do following calls
$class_a = new A();
$class_a->a();
c(); //references function c() within the same scope
The output would be:
Was called from function a() in class A
I'm just a simple function outside a class
But you could also do the following: outsource the function c() into an external file like function_c.php
Now, you can include/require the file from anywhere else and use it's content:
include 'function_c.php';
c(); //the function is now available, although it was defined in another file
you can a function from another class from a class, example:
require "myExternClass.php";
class myClass extends myExternClass
{
public function a() {
$this->b(); /* function b is in the class myExternClass */
}
}
generally you can't call a method of an object without the object itself.
but for some cases when method does not actually uses any objects' properties it may be acceptable for testing purposes to invoke it with call_user_func_array, passing some dummy value instead of object.
class A {
var $a;
function doNop() { echo "Nop";}
function doA() { echo "[".$a."]"; }
}
// instead of this
$a = new A;
$a->doNop();
// you _may_ use this
A::doNop();
// but this will fail, because there's no object to apply doA() to.
A::doA();
class A_dummy { $a };
// however, for testing purposes you can provide a dummy instead of real A instance
$b = new A_dummy;
call_user_func(array($b, 'A::doA'));
You can wrap the code in question inside a regular function:
function TestClass() {
$help = new Helper();
return $help->Test();
}
Then, in your index.php file you can call the function like this:
TestClass();
class MyClass {
var $lambda;
function __construct() {
$this->lambda = function() {echo 'hello world';};
// no errors here, so I assume that this is legal
}
}
$myInstance = new MyClass();
$myInstance->lambda();
//Fatal error: Call to undefined method MyClass::lambda()
So what is the correct syntax for reaching class variables ?
In PHP, methods and properties are in a separate namespace (you can have a method and a property with the same name), and whether you are accessing a property or a method depends of the syntax you are using to do so.
$expr->something() is a method call, so PHP will search something in the class' list of methods.
$expr->something is a property fetch, so PHP will search something in the class' list of properties.
$myInstance->lambda(); is parsed as a method call, so PHP searches for a method named lambda in your class, but there is no such method (hence the Call to undefined method error).
So you have to use the fetch property syntax to fetch the lambda, and then call it.
Since PHP 7.0, you can do this with ($obj->lambda)():
($obj->lambda)();
The parentheses make sure that PHP parses ($obj->lambda) as fetch the property named lambda. Then, () calls the result of fetching the property.
or you can do this with ->lambda->__invoke():
$myInstance = new MyClass();
$myInstance->lambda->__invoke();
__invoke is one of PHP's magic methods. When an object implements this method, it becomes invokable: it can be called using the $var() syntax. Anonymous functions are instances of Closure, which implements __invoke.
Or assign it to a local variable:
$lambda = $myInstance->lambda;
$lambda();
Or call it using call_user_func:
call_user_func($myInstance->lambda);
call_user_func can call any callable, including anonymous functions.
Alternatively, if this is a common pattern in your code, you can setup a __call method to forward calls to your lambda:
class MyClass
{
private $lambda;
public function __construct()
{
$this->lambda = function() {
echo "Hello world!\n";
};
}
public function __call($name, $args)
{
return call_user_func_array($this->$name, $args);
}
}
Now this works:
$myInstance = new MyClass();
$myInstance->lambda();
Since PHP 5.4 you can even do that in a trait:
trait LambdasAsMethods
{
public function __call($name, $args)
{
return call_user_func_array($this->$name, $args);
}
}
class MyClass
{
use LambdasAsMethods;
private $lambda;
public function __construct()
{
$this->lambda = function() {
echo "Hello World!\n";
};
}
}
$myInstance = new MyClass();
$myInstance->lambda();
You can also call your lambda function without change something in your class, using ReflectionFunction.
$myInstance = new MyClass();
$lambda = new ReflectionFunction($myInstance->lambda);
$lambda->invoke();
or if you have to pass arguments then
$args = array('arg'=>'value');
$lambda->invokeArgs($args);