I have two methods in a class, one of which is static. I want to access the non-static method from within the static method. Is that possible? I tried this:
class Foo {
public function qux(){
}
public static function waldo(){
self::qux(); // Non-static method Foo::qux() should not be called statically
}
}
Is making qux a static method the only way to achieve this? What if the user doesn't want qux() to be a static method?
This should work as you need:
class Foo {
public function qux(){
}
public static function waldo(){
$foo = new Foo();
$foo->qux();
}
}
There is no other way to call a dynamic method/function without creating the object itself first.
Of course, if you will use the object only one-time and call all methods or functions immediately, you could use something like this:
class Foo {
public function qux(){
}
public static function waldo(){
(new Foo())->qux();
}
}
class Foo {
public function qux(){
}
public static function waldo(){
$obj = new Static();
$obj->qux();
}
}
Related
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;
If I have a class like:
class MyClass
{
public function foo()
{
echo "foo";
}
}
And then outside of the class instantiate it and try to create an anonymous function in it:
$mine = new MyClass();
$mine->bar = function() {
echo "bar";
}
And then try to call it like $mine->bar(), I get:
Fatal error: Call to undefined method MyClass::bar() in ...
How can I create an anonymous function / closure on a class instance?
Aside: Before you tell me I should rethink my logic or use interfaces and OOP properly, in my case, it's a convenience method that applies to this specific instance of a bastardized class in an attempt to clean-up a legacy procedural application. And yes, I'm using PHP 5.3+
See my blog article here: http://blog.flowl.info/2013/php-container-class-anonymous-function-lambda-support/
You need to add a magic __call function:
public function __call($func, $args) {
return call_user_func($this->$func, $args);
}
The problem is that within this construct you can call private methods from public scope.
I suggest not to simply add new variables to a class that are not defined. You can avoid this using magic __set functions and catch all undefined variables in a container (= array, like in my blog post) and change the call_user_func behaviour to call only inside the array:
// inside class:
public $members = array();
public function __call($func, $args) {
// note the difference of calling only inside members:
return call_user_func($this->members[$func], $args);
}
__call
This will work.
class Foo {
public $bar;
public function __construct()
{
$this->bar = function()
{
echo 'closure called';
};
$this->bar();
}
public function __call($method, $args) {
return call_user_func($this->$method, $args);
}
}
new Foo();
The function IS being created.
PHP has a problem with calling it.
Dirty, but works:
$f = $mine->bar;
$f();
While reading this: http://propelorm.org/ I noticed that they are using -> sign on a static object and using several different methods of it as a "one-liner".
Or does the static object return an instance which from the methods are being called from?
What ever is the case I would like to read more about this. What is this called and does it really work with static objects?
I noticed that they are using -> sign on a static object
By static object you mean to say static method and that the code you are referring to is this:
classBookQuery::create()->findPK(123);
They are not using -> on a static method. They are using -> on the object returned by the static method.
You can try it yourself:
class AClass
{
public static function aMethod()
{
return new BClass();
}
}
class BClass
{
public function bMethod($int)
{
echo $int;
}
}
AClass::aMethod()->bMethod(123); // output: 123
As others have mentioned in the comments, the static function BookQuery::create() just returns another object.
The "arrow" operates on the returned object.
Example:
class Car {
public function beep() {
echo 'BEEP';
}
}
class CarProvider {
public static function get() {
return new Car();
}
}
// outputs 'BEEP';
CarProvider::get()->beep();
// the same as this
$car = CarProvider::get();
$car->beep();
This is oftentimes know as method chaining. The static method call is returning an instantiated object against which another method is called. This sort of construct is often achieve like this:
class myobject_factory {
public static function get_object () {
return new myobject;
}
}
class myobject {
protected $some_property;
public function set_some_property($value) {
$this->some_property = $value;
return $this;
}
public function get_some_propert() {
return $this->some_property;
}
}
$property = myobject_factory::get_object()->set_some_property('foobar')->get_some_property();
This is obviously a trivial example, but you can see how chaining is enabled because the setter on myobject returns $this.
ok I have this code, that I'm studying
class scope{
function printme(){
return "hello";
}
public static function printme(){
return "hello";
}
}
$s = new scope();
echo $s->printme(); //non-static call
echo "<br>";
echo scope::printme(); //static call
Now, this is not really the code of my project but these are the things I want to do
I want to create a class the will contain static and non-static functions.
I want a function to be available both on static and non-static calls.
As non-static function has a lot of operations on it, I also need to call it as a static function so that I will not need to instantiate the class. Is this possible? or I really needed to rewrite the function to another function or class?
NOTE: tell me if I'm doing some bad programming already.
Here is the rule:
A static method can be used in both static method and non-static method.
A non-static method can only be used in a non-static method.
If the instance of your class is rarely needed, you can have the static method create an instance, call the non-static method and return the value.
class Scope {
public function mynonstatic() {
}
public static function mystatic() {
$s = new Scope();
return $s->mynonstatic();
}
}
Remember that a static method is really just a global function with reduced scope. They are useful, but are should not be created without good reason.
As non-static function has a lot of operations on it, I also need to
call it as a static function so that I will not need to instantiate
the class. Is this possible? or I really needed to rewrite the
function to another function or class?
If you need it static, then make it static. If you need it not, then keep it the way it is. It is possible from within non-static function to call static function.
class Foo
{
public function bar()
{
Foo::zex();
// or self::zex() or even $this->zex();
}
public static function zex()
{
}
}
$foo = new Foo;
$foo->bar();
Ant the other way around.
class Foo
{
public function bar()
{
}
public static function zex()
{
$foo = new Foo;
$foo->bar();
}
}
When you should do it or should you do it at all is another question. The most common use of the latter is probably the Singleton pattern.
I am trying to create a simple MVC my personal use and I could really use an answer to this simple question
class theParent extends grandParent{
protected $hello = "Hello World";
public function __construct() {
parent::__construct();
}
public function route_to($where) {
call_user_func(array("Child", $where), $this);
}
}
class Child extends theParent {
public function __construct() {
parent::__construct();
}
public function index($var) {
echo $this->hello;
}
}
$x = new theParent();
$x->route_to('index');
Now Child::index() this throws a fatal error: Using $this when not in object context but if I were to use echo $var->hello, it works just fine.
I know I can use $var to access all properties in the parent, but I would rather use $this.
By writing call_user_func(array("Child", $where), $this) you are calling the method statically. But as your method isn't static you need some kind of object instance:
call_user_func(array(new Child, $where), $this);
Documentation on callback functions.
You don't have an instance of Child to call a non-static method upon when you're doing $x->route_to('index'); The way you're calling the method, without having made an instance first, is implied static.
There are two ways to correct it. Either make the Child class's methods static:
class Child extends theParent {
public function __construct() {
parent::__construct();
}
static public function index($var) {
echo self::$hello;
}
}
...or make an instance of the child class for the parent to use:
class theParent extends grandParent{
protected $hello = "Hello World";
private $child = false
public function __construct() {
parent::__construct();
}
public function route_to($where) {
if ($this->child == false)
$this->child = new Child();
call_user_func(array($this->child, $where), $this);
}
}
Of course, both of these samples are rather generic and useless, but you see the concept at hand.
$this gives you access to everything visible/accessible in the current object. That can either be in the class itself (this) or any of it's parents public or protected members/functions.
In case the current class overrides something of a parent class, you can access the parent method explicitly using the parent keyword/label, whereas you add :: to it regardless if it is not a static method.
Protected variables exist only once, so you can not use parent to access them.
Is this info of use?