Can I initiate an object instance and call a method inside another method in php?
Please give me examples at this question.. and show me separately all the combinations that can be done with methods and objects.
class Autorizare{
public function user(){
echo "This is a user";
}
}
class Derivata{
function derivata(){
echo "sunt o derivata";
}
$object = new Autorizare();
$object->user();
$object2 = new Derivata();
$object2->derivata();
}
echo $object->user();
echo $object2->derivata();
Something like this..
You can access methods of some class in these ways:
class A {
public function one() {
echo "This is a user";
}
public static function two() {
echo "This is not a user";
}
public function test() {
$this->one(); //for non static methods
self::two(); //for static methods
}
}
class B {
public function test1() {
$a = new A();
$a->one(); //for non static methods
}
public function test2() {
A::two(); //for static methods
}
}
$obj = new B();
$obj->test1();
$obj->test2();
For more details and also how to use scope look at php manual
*edit code upon comment request
Related
How to create a class that can call multiple functions?
example:
class ClassName
{
public static function func1()
{
}
public static function func2()
{
}
public static function func3()
{
}
}
ClassName::func1()->func2()->func3();
result
Uncaught Error: Call to a member function funcX() on null
In PHP you cannot call static functions "piggybacked" like you can in, say, JavaScript. You have a few options .. Call them in a list, one at a time .. Like so:
ClassName::func1();
ClassName::func2();
ClassName::func3();
Or Like
$foo = new ClassName;
$foo->func1();
$foo->func2();
$foo->func3();
Now if you want to run them all with a single call, you need to nest the functions BUT we have to rid ourselves of the static method ...
<?php
class ClassName
{
public function func1()
{
echo "1 \n";
$this->func2();
}
public function func2()
{
echo "2 \n";
$this->func3();
}
public function func3()
{
echo "3 \n";
}
}
$foo = new ClassName;
$foo->func1();
Finally, if you want to run all of your functions within a class sequentially, you can use get_class_methods and loop through all the functions ... IE
<?php
class ClassName
{
public static function func1()
{
echo "1 \n";
}
public static function func2()
{
echo "2 \n";
}
public static function func3()
{
echo "3 \n";
}
}
$functions = get_class_methods('Classname');
foreach ($functions as $function){
ClassName::$function();
}
Both methods will result in:
1
2
3
If you choose to rid yourself of the static method however (as seen in our "nested function").. And you just choose public .. Then your syntax is possible using #arkascha's method of building out.
public function func1(): ClassName { // From #arkascha's answer ..
$foo = new ClassName;
$foo->func1()->func2()->func3();
The difference is understanding public method and static method
This won't work at all with static methods as you suggest.
This is possible however with an instance object, that is called "builder pattern" or "fluent style":
<?php
class ClassName {
public function func1(): ClassName {
echo "1";
return $this;
}
public function func2(): ClassName {
echo "2";
return $this;
}
public function func3(): ClassName {
echo "3";
return $this;
}
}
(new ClassName())->func1()->func2()->func3();
The output is:
123
Firstly, you need to create static instance for making chain methods. Because your methods are static and cant use them like chain. After it, you need to return this function every time at the end method. Like this:
class ClassName
{
private static $self;
public static function func1()
{
echo ' i am '.__METHOD__." \n";
return self::instance();
}
public static function func2()
{
echo ' i am '.__METHOD__." \n";
return self::instance();
}
public static function func3()
{
echo ' i am '.__METHOD__." \n";
return self::instance();
}
public static function instance(){
return self::$self ?? self::$self = new static ;
}
}
ClassName::func1()->func2()->func3();
How can I create something like
MyObject->property->method()
in PHP?
I only know how to create a method for a class:
class MyObject
{
public function MyMethod()
{
// do something
}
}
In Javascript I can easily do something like
var MyObject = {
property : {
method : function ()
{
// do something
}
}
}
How do I do that?
In Javascript you can create objects and methods inline, in PHP you need to have a class and instantiate it:
class Foo {
public function method() {}
}
class MyObject {
public $property;
public function __construct() {
$this->property = new Foo;
}
}
$o = new MyObject;
$o->property->method();
You can set an object as the value of a property. Something like this:
class Foo {
public $Bar;
public function __construct() {
$this->Bar = new Bar();
}
}
class Bar {
public function ShowBar() {
echo 'Bar';
}
}
$Foo = new Foo();
$Foor->Bar->ShowBar();
As others have correctly answered, this works differently in PHP and Javascript. And these differences are also the reason why in PHP you need to define the class methods before you run them. It might become a bit more dynamic in the future but I'm sure not on the level of Javascript.
You can however fake this a bit in PHP because you can assign functions to properties dynamically:
$myObject = new PropCall;
$myObject->property->method = function() {
echo "hello world\n";
};
$myObject->property->method();
This example outputs:
hello world
This does work because some little magic has been added in the instantiated object:
class PropCall
{
public function __call($name, $args) {
if (!isset($this->$name)) {
return null; // or error handle
}
return call_user_func_array($this->$name, $args);
}
public function __get($name) {
$this->$name = new PropCall;
return $this->$name;
}
}
This class code checks if a dynamic property has been added with the name of the method called - and then just calls the property as a function.
Say object of class B is attribute of class A. How can I call method of object of class A from method of object of class B? What would be nice solution without passing object link?
Thanks!
Here goes code sample:
class A{
var $b;
function __construct(){
$this->b = new B();
}
function f1(){
$this->b->f3();
}
function f2(){
echo 'hello!';
}
}
class B{
function f3(){
// call f2() method in object $obj(not new A())
}
}
$obj = new A();
$obj->f1();
You can use a static function
public static function f2{
echo 'hello!';
}
with f3 defined as
function f3(){
A::f2();
}
This may not ultimately be the solution you want, however. See more info here.
The only way you can access that instance's function is if you inject it on the B object as a dependency. You can inject it within the constructor, like this:
<?php
class A {
protected $b;
public function __construct() {
$this->b = new B($this);
}
public function f1() {
$this->b->f3();
}
public function f2() {
echo 'hello!';
}
}
class B {
protected $a;
public function __construct($a) {
$this->a = $a;
}
public function f3() {
$this->a->f2();
}
}
$obj = new A();
$obj->f1();
Is there a way to call an inherited method, without specifying it's function name?
Something like:
class Child extends Parent {
function some_function(){
// magically inherit without naming the parent function
// it will call parent::some_function()
parent::inherit();
// other code
}
function another_function(){
// it will call parent::another_function()
$result = parent::inherit();
// other code
return $result;
}
}
I could think of a hack to do this using debug_backtrace(), get the last function where inherit() was called and access it's parent with the same function name. I was wondering if there's a nicer way instead of using debug functions which are clearly not meant for this.
You can use the magic __FUNCTION__ constant.
class A
{
function some_function()
{
echo 'called ' . __METHOD__;
}
}
class B extends A
{
function some_function()
{
call_user_func(array('parent', __FUNCTION__));
}
}
$b = new B;
$b->some_function(); // prints "called A::some_function"
Instead of
call_user_func(array('parent', __FUNCTION__));
you can also do
parent::{__FUNCTION__}();
Dirty, but:
class Adult {
function mummy(){
return 'Walk like an Egyptian';
}
function daddy(){
return 'Luke, I am your father';
}
}
class Child extends Adult {
function mummy(){
echo 'Mummy says: ';
$me = explode('::',__METHOD__)[1];
echo parent::$me();
}
function daddy(){
echo 'Daddy says: ';
$me = explode('::',__METHOD__)[1];
echo parent::$me();
}
}
$o = new Child();
$o->mummy();
$o->daddy();
EDIT
Actually giving you a parent method called inherit();
class Adult {
private function mummy(){
return 'Walk like an Egyptian';
}
private function daddy(){
return 'Luke, I am your father';
}
protected function inherit($method) {
$beneficiary = explode('::', $method)[1];
return $this->$beneficiary();
}
}
class Child extends Adult {
public function mummy() {
echo 'Mummy says: ',
parent::inherit(__METHOD__),
PHP_EOL;
}
public function daddy() {
echo 'Daddy says: ',
parent::inherit(__METHOD__),
PHP_EOL;
}
}
$o = new Child();
$o->mummy();
$o->daddy();
Dynamically calling functions:
static::$functionName();
In your case:
$func = __FUNCTION__;
parent::$func();
Note: the function name must be a string, if it's the actual function (not really relevant in this context) then it first needs to be converted to its string name first.
Other stuff that your question will probably lead you towards in the long run.
Check out late static binding it's what you're looking for.
Example taken from the linked page.
class A {
public static function who() {
echo __CLASS__;
}
public static function test() {
static::who(); // Here comes Late Static Bindings
}
}
class B extends A {
public static function who() {
echo __CLASS__;
}
}
B::test();
Given class A that extends class B, how can I have calls to class A's __call function override the matching function inherited from the parent?
Consider this simplified example:
class A
{
public function method_one()
{
echo "Method one!\n";
}
}
class B extends A
{
public function __call($name, $args)
{
echo "You called $name!\n";
}
}
$b = new B();
$b->method_one();
When I run it, I get the output Method one!. I WANT to get the output You called method_one!.
So, how do I have the subclass's magic method override the parent classes defined method?
I need to extend the object, because I need access to a protected method in A, but I want to channel all public methods into my own __call handler. Is there any way to do this?
So, I found a way to do it, which involves making an intermediate class to expose the protected method I need, while still using __call for the public ones. This works, but I really don't like the idea of extending a class just to expose a protected method... Still, someone might find it useful, so thought I'd share:
class A
{
public function method_one()
{
echo "Method one!\n";
}
protected function protected_method()
{
echo "Accessible!\n";
}
}
class A_accessor extends A
{
public function publicise()
{
$args = func_get_args();
return call_user_func_array(array($this, array_shift($args)), $args);
}
}
class B
{
private $A;
public function __construct()
{
$this->A = new A_accessor();
}
public function __call($name, $args)
{
echo "You called $name!\n";
}
public function protected_method()
{
return $this->A->publicise('protected_method');
}
}
$b = new B();
$b->method_one();
$b->protected_method();
This is the answer I actually used, based on Mark Baker's comment.
By having an object of the class whose methods I want access to as a variable, I can use ReflectionMethod to access any of its methods just as if I was extending it, but with __call still catching everything else. So any methods I want to pass through, I can pass through with something like this:
public function __call($name, $args)
{
$method = new ReflectionMethod($this->A, $name);
$method->setAccessible(true);
return $method->invokeArgs($this->A, $args);
}
Or in my case, with the full class like this:
class B
{
private $A;
public function __construct()
{
$this->A = new A();
}
public function __call($name, $args)
{
echo "You called $name!\n";
}
public function protected_method()
{
$method = new ReflectionMethod($this->A, 'protected_method');
$method->setAccessible(true);
return $method->invoke($this->A, $args);
}
}
try this
class A1
{
protected function method_one()
{
echo "Method one!\n";
}
}
class B1
{
private $A;
public function __construct()
{
$this->A = new A1;
}
public function __call($name, $args)
{
$class = new ReflectionClass($this->A);
$method = $class->getMethod($name);
$method->setAccessible(true);
//return $method;
echo "You called $name!\n";
$Output=$method->invokeArgs($this->A, $args);
$method->setAccessible(false);
return $Output;
}
}
$a = new B1;
$a->method_one("");