Here the problem that occurs when calling the functions in a non-static way, is that at some point it could happen that a method was called that does not exist .
However, the first error is to create an array in this way:
$this->tables = ('a','b','n');
Ideally, do it like this:
$this->tables = array('a','b','n', 'z'); // <------- mejor así !
$this->tables = ['a','b','n', 'z']; // <------- o así !
The quick way:
class MyClass1
{
private $tables;
function __construct()
{
$this->tables = array('a', 'b', 'n', 'z');
}
/**
* Lo rápido
* Pero si no existe el método lanza un error:
* Fatal error: Call to undefined method MyClass::migration_z() in //...
*/
public function runMigrations1()
{
foreach($this->tables as $table)
{
$method = 'migration_' . $table;
$array[] = $this->$method();
}
return $array;
}
private function migration_a()
{
return 'a';
}
private function migration_b()
{
return 'b';
}
private function migration_n()
{
return 'n';
}
}
The problem is that if the method does not exist, it throws an error. Which we could control by:
class MyClass2
{
/**
* La segunda opción para evitar errores
* Comprobar que el método lamado existe mediante getMethod()
*/
public function runMigrations2()
{
foreach($this->tables as $table)
{
$method = 'migration_' . $table;
$array[] = $this->getMethod($method);
}
return $array;
}
private function getMethod($method)
{
if(method_exists($this, $method)):
return $this->$method();
else:
return null;
endif;
}
}
If you decide to continue with the practice of using call_user_func
a correct way would be like this:
class MyClass3
{
/**
* El problema es igual que runMigrations1()
* Si el método llamado no existe, lanza un error de tipo:
* Warning: call_user_func() expects parameter 1 to be a valid callback,
* class 'MyClass' does not have a method 'migration_z' in //...
*/
public function runMigrations3()
{
foreach($this->tables as $table)
{
$method = 'migration_' . $table;
$array[] = call_user_func(array($this, $method));
}
return $array;
}
}
Errors, whenever they are likely to occur, should be controlled to follow good practices.
class MyClass4
{
/**
* Podemos solucionarlo contorlando el error
*/
public function runMigrations4()
{
foreach($this->tables as $table)
{
$method = 'migration_' . $table;
$array[] = $this->getMethodCallUserFunc($method);
}
return $array;
}
private function getMethodCallUserFunc($method)
{
if(method_exists($this, $method)):
return call_user_func(array($this, $method));
else:
return null;
endif;
}
}
If you make a var_dump()
on any of the runMigrations
you will see the result that each one throws, except for those that throw error because they do not find the z
method created in error mode.
$instance = new MyClass1(); // 2, 3, 4
var_dump($instance->runMigrations1()); // 2, 3, 4
It will give a result like this with those that have error control
array (size=4)
0 => string 'a' (length=1)
1 => string 'b' (length=1)
2 => string 'n' (length=1)
3 => null