automatically call all method inside the class in php - php

Is there a way to call all the methods from a class once the class is initialized? For example, lets say I have a class named todo and once I make an instance of a todo class, all the methods/functions inside it will be executed, without calling it in the constructor?
<?php
class todo
{
function a()
{
}
function b()
{
}
function c()
{
}
function d()
{
}
}
$todo = new todo();
?>
In here I created an instance of a class todo so that the methods a, b, c, d will be executed. Is this possible?

This outputs 'abc'.
class Testing
{
public function __construct()
{
$methods = get_class_methods($this);
forEach($methods as $method)
{
if($method != '__construct')
{
echo $this->{$method}();
}
}
}
public function a()
{
return 'a';
}
public function b()
{
return 'b';
}
public function c()
{
return 'c';
}
}

I think you can use iterator. All methods will be called in foreach PHP Iterator

Use a __construct() method (as you mentioned), which is called on object instantiation. Anything else would be unfamiliar and unexpected (to have random methods instantly executed not by the constructor).
Your class code looks like you're using PHP4, if that's the case, name your constructor the same as the class name.

Like this? I use this pattern to register meta data about classes sometimes.
<?php
class todo {
public static function init() {
self::a();
self::b();
self::c();
self::d();
}
function a()
{
}
function b()
{
}
function c()
{
}
function d()
{
}
}
todo::init();

There isn't any way that I can think of, short of putting it into the constructor as you suggest in your question:
<?php
class todo
{
public function __construct()
{
$this->a();
$this->b();
$this->c();
$this->d();
}
function a()
{
}
function b()
{
}
function c()
{
}
function d()
{
}
}
$todo = new todo();
?>

I copied and pasted below class from php.net...
I thought it will be usefull because methods are not called using objects, instead using get_class_methods():
class myclass {
function myclass()
{
return(truenter code heree);
}
function myfunc1()
{
return(true);
}
function myfunc2()
{
return(true);
}
}
$class_methods = get_class_methods('myclass');
foreach ($class_methods as $method_name) {
echo "$method_name\n";
}

Related

How to handle __invoke() method does not exist in PHP?

The magical __call() and __callStatic can pretty much handle any non existing method on the class, but is there a way to handle a non existing magical method on a class?!
Here's an example on why I need this:
I have a class called DoSomething:
class DoSomething{
public function ok(){
echo 'Something!';
}
}
I want to call this class as a function for a reason! which should call the __invoke function of that class:
$doSomething = new DoSomething();
$doSomething();
Normally by doing that, the class should look for the __invoke function, however in my case I don't to have that function declared on my class (DoSomething), instead I want to be able to call another function (such as the ok()) if the __invoke doesn't exist.
I was expecting something like this to work, but of course it didn't :)
public function __call($class, $arguments)
{
$object = IoC::resolve($class);
$object->ok(...$arguments);
}
The main goal is to use the class as a function, without having to declare the __invoke method. Handle the function does not exist error and call another function instead.
I think that would be really cool :D I appreciate suggestions or other solutions to achieve this.
Internal solution
Extract an abstract class
You could extract an abstract class and have your classes extend it:
<?php
abstract class Invokable
{
public function __invoke()
{
return $this->ok();
}
abstract public function ok();
}
class DoSomething extends Invokable
{
public function ok()
{
echo 'Something';
}
}
$doSomething = new DoSomething();
echo $doSomething();
For an example, see:
https://3v4l.org/m0ih8
Extract a trait
You could extract a trait and have your classes use it:
<?php
trait InvokableTrait
{
public function __invoke()
{
return $this->ok();
}
}
class DoSomething
{
use InvokableTrait;
public function ok()
{
echo 'Something';
}
}
$doSomething = new DoSomething();
echo $doSomething();
For an example, see:
https://3v4l.org/ftUfI
External Solution
Create a proxy
You could create a proxy (a decorator) that composes the object that is not invokable:
<?php
class InvokableDecorator
{
private $decorated;
public function __construct($decorated)
{
$this->decorated = $decorated;
}
public function __call($name, $arguments)
{
/**
* delegate to decorated object if the method exists
*/
if (method_exists($this->decorated, $name)) {
return $this->decorated->{$name}($arguments);
}
}
public function __invoke()
{
return $this->decorated->ok();
}
}
class DoSomething
{
public function ok()
{
echo 'Something';
}
}
$doSomething = new InvokableDecorator(new DoSomething());
echo $doSomething();
For an example, see:
https://3v4l.org/C3XEX
Create a handler
You could create a handler that takes care of determining this externally:
<?php
class Handler
{
public function handle($subject)
{
if (is_callable($subject)) {
return $subject();
}
if (method_exists($subject, 'ok')) {
return $subject->ok();
}
throw new \BadMethodCallException(sprintf(
'Unable to handle instance of "%s"',
get_class($subject)
));
}
}
class DoSomething
{
public function ok()
{
echo 'Something';
}
}
$handler = new Handler();
echo $handler->handle(new DoSomething());
For an example, see:
https://3v4l.org/E0NVs

call a function before method call

Design question / PHP:
I have a class with methods.
I would like to call to an external function anytime when any of the methods within the class is called.
I would like to make it generic so anytime I add another method, the flow works with this method too.
Simplified example:
<?php
function foo()
{
return true;
}
class ABC {
public function a()
{
echo 'a';
}
public function b()
{
echo 'b';
}
}
?>
I need to call to foo() before a() or b() anytime are called.
How can I achieve this?
Protect your methods so they're not directly accessible from outside the class, then use the magic __call() method to control access to them, and execute them after calling your foo()
function foo()
{
echo 'In pre-execute hook', PHP_EOL;
return true;
}
class ABC {
private function a()
{
echo 'a', PHP_EOL;
}
private function b($myarg)
{
echo $myarg, ' b', PHP_EOL;
}
public function __call($method, $args) {
if(!method_exists($this, $method)) {
throw new Exception("Method doesn't exist");
}
call_user_func('foo');
call_user_func_array([$this, $method], $args);
}
}
$test = new ABC();
$test->a();
$test->b('Hello');
$test->c();

Can I call inherited parent method without a name in PHP?

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();

Calling static function from instance

I'm trying to call a static magic function (__callStatic) from a member of its child class. Problem being, it goes to the non-static __call instead.
<?php
ini_set("display_errors", true);
class a
{
function __call($method, $params)
{
echo "instance";
}
static function __callStatic($method, $params)
{
echo "static";
}
}
class b extends a
{
function foo()
{
echo static::bar();
// === echo self::bar();
// === echo a::bar();
// === echo b::bar();
}
}
$b = new b();
echo phpversion()."<br />";
$b->foo();
?>
Output:
5.3.6
instance
How can I make it display "static"?
If you remove the magic method '__call', your code will return 'static'.
According to http://php.net/manual/en/language.oop5.overloading.php "__callStatic() is triggered when invoking inaccessible methods in a static context".
What I think is happening in your code is that,
You are calling static method from a non-static context.
The method call is in non-static context, so PHP searches for the magic method '__call'.
PHP triggers the magic method '_call' if it's exists. Or, if it's not exists it will call '_callStatic'.
Here is a possible solution:
class a
{
static function __callStatic($method, $params)
{
$methodList = array('staticMethod1', 'staticMethod2');
// check if the method name should be called statically
if (!in_array($method, $methodList)) {
return false;
}
echo "static";
return true;
}
function __call($method, $params)
{
$status = self::__callStatic($method, $params);
if ($status) {
return;
}
echo "instance";
}
}
class b extends a
{
function foo()
{
echo static::staticMethod1();
}
function foo2()
{
echo static::bar();
}
}
$b = new b();
echo phpversion()."<br />";
$b->foo();
$b->foo2();
In PHP there are the reserved words self and parent for accessing static methods from within a class and/or instantiated object. parent refers to inherited methods from the parent class.
class b extends a
{
function foo()
{
echo parent::bar();
}
}
EDIT: Uhm, that doesn't do the trickā€¦ (using PHP 5.3.5)
$b = new b();
$b->foo(); // displays: instance
a::bar(); // displays: static
2nd EDIT: Ha, it works only, if you omit the __call()-method in class a.
class a
{
static function __callStatic($method, $params)
{
echo "static";
}
// function __call($method, $params)
// {
// echo "instance";
// }
}
class b extends a
{
function foo()
{
echo parent::bar();
}
}
$b = new b();
$b->foo(); // displays: static
a::bar(); // displays: static

PHP - Automatically call one one before another?

In PHP, is there any way to make class method automatically call some other specified method before the current one? (I'm basically looking to simulate before_filter from Ruby on Rails.
For example, calling function b directly but getting the output 'hello you'.
function a()
{
echo 'hello';
}
function b()
{
echo 'you';
}
Any advice appreciated.
Thanks.
Check this:
class Dispatcher {
/*
* somewhere in your framework you will determine the controller/action from path, right?
*/
protected function getControllerAndActionFromPath($path) {
/*
* path parsing logic ...
*/
if (class_exists($controllerClass)) {
$controller = new $controllerClass(/*...*/);
if (is_callable(array($controller, $actionMethod))) {
$this->beforeFilter($controller);
call_user_func(array($controller, $actionMethod));
/*..
* $this->afterFilter($controller);
* ...*/
}
}
}
protected function beforeFilter($controller) {
foreach ($controller->beforeFilter as $filter) {
if (is_callable(array($controller, $filter))) {
call_user_func(array($controller, $filter));
}
}
}
/*...*/
}
class FilterTestController extends Controller {
protected $beforeFilter = array('a');
function a() {
echo 'hello';
}
function b() {
echo 'you';
}
}
PHP does not support filters.However, you could just modefy your own function to ensure that a() is always run before b().
function a()
{
echo 'hello';
}
function b()
{
a();
echo 'you';
}
Not if you're not willing to override a b() to call both.
You might be interested in AOP for PHP though.
How about this:
function a()
{
echo 'hello';
}
function b()
{
a();
echo 'you';
}
If you are under a class and both functions are in that class:
function a()
{
echo 'hello';
}
function b()
{
$this->a();
echo 'you';
}
Not sure but possibly that's what you are looking for. thanks

Categories