PHP - Automatically call one one before another? - php

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

Related

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

Get name function in PHP

I have some classes:
class A
{
private $_method;
public function __construct()
{
$this->_method = new B();
}
public function demo()
{
$this->_method->getNameFnc();
}
}
class B
{
public function getNameFnc()
{
echo __METHOD__;
}
}
I'm trying to get the function name of a class B class, but I want the function getNameFnc to return 'demo'. How do I get the name 'demo' in function getNameFnc of class B?
Well, if you really want to do this without passing a parameter*, you may use debug_backtrace():
→ Ideone.com
public function getNameFnc()
{
$backtrace = debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT, 2);
echo $backtrace[1]['function'];
}
* this would be the recommended way although one should never need to know which function has been previously called. If your application relies on that fact, you have got a major design flaw.
You will need to use debug_backtrace to get that information.
I haven't tested the code below but I think this should give you the information you want:
$callers = debug_backtrace();
echo $callers[1]['function'];
Why not pass it?
class A
{
private $_method;
public function __construct()
{
$this->_method = new B();
}
public function demo()
{
$this->_method->getNameFnc(__METHOD__);
}
}
class B
{
public function getNameFnc($method)
{
echo $method;
}
}
Or use __FUNCTION__ if you don't want the class name.

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

automatically call all method inside the class in 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";
}

php extending but with a new constructor...possible?

I have a class:
class test {
function __construct() {
print 'hello';
}
function func_one() {
print 'world';
}
}
what I would like to do is a have a class that sort of extends the test class. I say 'sort of', because the class needs to be able to run whatever function the test class is able to run, but NOT run the construct unless I ask it to. I do not want to override the construct. Anyone has any idea how to achieve this?
class test {
function __construct() {
print 'hello';
}
function func_one() {
print 'world';
}
}
class test_2 extends test {
function __construct() {
if (i want to) {
parent::__construct();
}
}
}
What's wrong with overriding the construct?
class foo extends test {
function __construct() { }
}
$bar = new foo(); // Nothing
$bar->func_one(); // prints 'world'
You could define a "preConstructor" method in your sub-classes that your root-class constructor would execute, and use a boolean flag to determine whether constructor code should be executed.
Like so:
class test
{
protected $executeConstructor;
public function __construct()
{
$this->executeConstructor = true;
if (method_exists($this, "preConstruct"))
{
$this->preConstruct();
}
if ($this->executeConstructor == true)
{
// regular constructor code
}
}
}
public function subTest extends test
{
public function preConstruct()
{
$this->executeConstructor = false;
}
}

Categories