How to auto call function in php for every other function call
Your best bet is the magic method __call, see below for example:
<?php
class test {
function __construct(){}
private function test1(){
echo "In test1", PHP_EOL;
}
private function test2(){
echo "test2", PHP_EOL;
}
protected function test3(){
return "test3" . PHP_EOL;
}
public function __call($method,$arguments) {
if(method_exists($this, $method)) {
$this->test1();
return call_user_func_array(array($this,$method),$arguments);
}
}
}
$a = new test;
$a->test2();
echo $a->test3();
/*
* Output:
* In test1
* test2
* In test1
* test3
*/
Please notice that test2
and test3
are not visible in the context where they are called due to protected
and private
. If the methods are public the above example will fail.
test1
does not have to be declared private
.
ideone.com example can be found here
Updated: Add link to ideone, add example with return value.
Call function before each function
There are different approaches to solve your problem. Some of them are mentioned in the comments already. Let us take the simplest approaches for solving your issue.
The magic method __call()
As lovelace said in the comments, there is already a simple solution for your problem stated in another stack overflow article. It uses PHPs own magic method __call(). Let 's have a look at a simple example.
class Foo
{
protected function before() : void
{
echo "before";
}
public function after() : void
{
echo "after";
}
public function __call($method, $arguments) : void
{
if (method_exists($this, $method)) {
$this->before();
return call_user_func_array(array($this, $method), $arguments);
}
}
}
// Testing
$class = new Foo();
$class->after(); // echoes "before->after"
As you can see the magic method __call
provides proper handling for your purpose. First it checks, if the called method exists and after that it executes the before
method before the called method is executed. The before
method is called automatically, when you call a class method, that exists.
The callback approach
As also mentioned in the comments a callback function could be a possible solution without handling class instances. Let 's have a look at the callback example.
$callback = function()
{
echo "before->";
}
function foo(callable $callback, $bla)
{
$callback();
echo $bla;
}
// example code
foo($callback, 'go and make some coffee');
// output: "before->go and make some coffee"
This approach is even simpler as using the __call
method, because you need just a callable function as parameter for your functions. Easy, hm?
The observer pattern
The observer pattern came with the standard php library in php5 and is more complex. I guess way too complex for your use case. To keep it complete, here 's a short example, how the observer pattern could be a usable solution to your issue.
class Group implements SplSubject
{
/**
* persons in this group
* @var \SplObjectStorage
*/
protected $persons;
/**
* observer active in this group
* @var \SplObjectStorage
*/
protected $observers;
/**
* the person, which actually speaks
* @var Person
*/
protected $speaker;
/**
* Initializes our class members and sets an observer for this group
*/
public function __construct()
{
$this->persons = new \SplObjectStorage();
$this->observers = new \SplObjectStorage();
$onSpeakObserver = new OnSpeakObserver($who, $what);
$this->attach($onSpeakObserver);
}
public function add(Person $person) {
$this->persons->attach($person);
}
public function speak(Person $who, $what) {
echo $who . " says: " . $what . "<br>";
$this->speaker = $who;
$this->notify();
}
public function getSpeaker() {
return $this->speaker;
}
public function getGroup() {
return $this->persons;
}
public function attach(\SplObserver $observer) {
$this->observers->attach($observer);
}
public function detach(\SplObserver $observer) {
$this->observers->attach($observer);
}
public function notify() {
foreach ($this->observers as $observer) {
$observer->update($this);
}
}
}
This is our basic class called group
, which should be observed. A class, which should be observed, is always called the "subject". A subject takes one ore more observers, which are called by the notify
method of the subject. A group consists of several people and a speaker. There is always one speaker and the other persons are listeners, which can react, when the speaker says something. For the reaction of the listeners we need an observer. This observer listens, if the speaker says something. The observer is added directly in the constructor of the group.
This class implements the \SplSubject
interface, which brings us the methods attach
, detach
and notify
for handling the observer, we attach to the group. Next we need the classes for a person and the observer itself.
class Person
{
protected $name = '';
public function __construct(string $name) : void
{
$this->name = $name;
}
public function __toString() : string
{
return $this->name;
}
}
A simple person with a name.
class OnSpeakObserver implements \SplObserver
{
public function update(\SplSubject $subject)
{
foreach ($subject->getGroup() as $person) {
if ($person !== $subject->getSpeaker()) {
echo $person . " says: me!<br>";
}
}
}
}
This is our observer, which implements the native \SplObserver
interface, which forces us to use the update method. This method is called every time, when a person in the group speaks.
With this the classes, we have a simple observer pattern. In this simple example the observer forces a reaction every time a person in a group says something.
// open a group (the subject, which is observed)
$friends = new Group();
// add some persons to our group
$sarah = new Person('Sarah');
$friends->add($sarah);
$nicole = new Person('Nicole');
$friends->add($nicole);
$marcel = new Person('Marcel');
$friends->add($marcel);
$steffen = new Person('Steffen');
$friends->add($steffen);
// Marcel says ...
$friends->speak($marcel, 'Who likes the observer pattern?');
// result:
// Marcel says: Who likes the observer pattern?
// Sarah says: me!
// Nicole says: me!
// Steffen says: me!
You could transfer this little example to solve your problem. An observer could listen on the execution of your functions and every time one of your functions is called, the observer could execute another function before. As shown in this example, the observer does nothing more than executing, after a person in a group has said something. Same goes for your issue. It all depends on when the notify method of the subject is called.
If you have any questions feel free to ask.
Call a function from another function in PHP
If you are using a class, then you can use $this
for calling the function:
class Test {
public function say($a) {
return $a ;
}
public function tell() {
$c = "Hello World" ;
$a = $this->say($c) ;
return $a ;
}
}
$b= new Test() ;
echo $b->tell() ;
If you are using a normal function, then use closure:
function tell(){
$a = "Hello" ;
return function($b) use ($a){
return $a." ".$b ;
} ;
}
$s = tell() ;
echo $s("World") ;
Auto call a php function every 10 seconds
You just need to put it in a function and call it again when it's finish.
function ajaxCall() {
$.ajax({
...
}.always(function() {
setTimeout(ajaxCall, 10000); // 10 seconds
});
}
ajaxCall();
EDIT
Updated due to roasted comment.
Is it possible to run a function when another function starts and another function when a function ends?
Measuring execution time is the domain of profilers. In PHP, you could use Xdebug to do so. See Simplest way to profile a PHP script for other suggestions. In any case, a profiler is what you want to use. It's a professional tool for the purpose.
As an alternative, you could invest into an observability tool, like Instana or Tideways. There are others. While observability is somewhat different from profiling, both tools come with code profiling capabilities to complement their observability features. Full disclosure: I work for Instana and am friends with the owner of Tideways.
I am not aware of a good userland no-code approach to adding interceptors to function calls. There are libraries like Componere, runkit or uopz but I don't think you'll get very far with them and you will need to install an extension. If given the choice between installing Xdebug or one of these, I'd go with Xdebug.
A low code approach might be to use attributes as pointed out in the comments to your question. That will still require you to heavily touch up your code because every line of code you want measured needs to have the attribute.
Apart from that, you could hack something together in a namespace:
<?php
namespace My;
foreach (get_defined_functions()['internal'] as $function) {
if ($function === 'assert') continue;
$declaration = sprintf(
'namespace My; function %s() {
$start = \microtime(true);
$retval = \call_user_func_array("%s", \func_get_args());
echo \microtime(true) - $start, PHP_EOL;
return $retval;
}',
$function,
$function,
$function,
$function
);
eval($declaration);
};
echo strtotime('today');
This will output something like
6.9141387939453E-5
1624485600
Demo: https://3v4l.org/r9Rpd
This will create a function for every internal PHP function in the namespace My
, wrapping that internal function. You can insert any code you want to run before and after the function in the function declaration.
PHP will first check the current namespace for a defined function before falling back to looking into the global namespace. Thus, when calling strtotime
, it will invoke My\strtotime
.
There are probably plenty of caveats I didn't think through with this approach. I am not recommending to use that. As I said in the beginning: use a profiler.
Calling function at the beginning of every action
You have two options here.
The first option, override the constructor:
public function __construct()
{
parent::__construct(); // Call parent constructor
$this->someFunction(); // Call your function
}
Don't forget to call the parent constructor (Constructor of the CController class) and after that, call your action.
The second option you have is to override the 'beforeAction' function
protected function beforeAction($action)
{
return true; // True: the action should be executed, false if not.
}
Hope it helps you :).
Making a method in PHP automatically run some code after being called. Possible?
A far simpler way to do this would to simply have a third method which calls run()
and then calls common_code()
. Subclasses can then override run()
all they want.
abstract class Parent_Class {
public abstract function run();
protected function common_code() {
// Common code here
}
protected function start() {
$this->run();
$this->common_code();
}
}
class Child_Class {
public function run() {
// Code here
}
}
Related Topics
PHP Fatal Error: Call to Undefined Function MySQLi_Stmt_Get_Result()
Sort Multi-Dimensional Array by Specific Key
PHP Upload, Extract and Progressbar
How to Add a New Method to a PHP Object on the Fly
How to Re-Save the Entity as Another Row in Doctrine 2
PHP Built in Server and .Htaccess Mod Rewrites
How to Check If a Request If Coming from the Same Server or Different Server
Fastest Way to Retrieve a <Title> in PHP
Why Is Mime_Content_Type() Deprecated in PHP
Is MySQL_Insert_Id Safe to Use
Redirect to Page and Send Custom Http Headers
How to Show a Where Clause Just for One Field in MySQL
Laravel Catch Tokenmismatchexception
How to Make PHP Generate Chunked Response
How to Fetch Associative Array Grouped by the Values of a Specified Column with Pdo