Is it possible to alias a function with a different name in PHP? Suppose we have a function with the name sleep. Is there a way to make an alias called wait?
By now I'm doing like this:
function wait( $seconds ) {
sleep($seconds);
}
Until PHP 5.5
yup, function wait ($seconds) { sleep($seconds); } is the way to go. But if you are worried about having to change wait() should you change the number of parameters for sleep() then you might want to do the following instead:
function wait() {
return call_user_func_array("sleep", func_get_args());
}
PHP 5.6+ only
Starting with PHP 5.6 it is possible to alias a function by importing it:
use function sleep as wait;
There's also an example in the documentation (see "aliasing a function").
Nope, but you can do this:
$wait = 'sleep';
$wait($seconds);
This way you also resolve arguments-number-issues
You can look at lambdas also if you have PHP 5.3
$wait = function($v) { return sleep($v); };
If you aren't concerned with using PHP's "eval" instruction (which a lot of folks have a real problem with, but I do not), then you can use something like this:
function func_alias($target, $original) {
eval("function $target() { \$args = func_get_args(); return call_user_func_array('$original', \$args); }");
}
I used it in some simple tests, and it seemed to work fairly well. Here is an example:
function hello($recipient) {
echo "Hello, $recipient\n";
}
function helloMars() {
hello('Mars');
}
func_alias('greeting', 'hello');
func_alias('greetingMars', 'helloMars');
greeting('World');
greetingMars();
No, there's no quick way to do this in PHP. The language does not offer the ability to alias functions without writing a wrapper function.
If you really really really needed this, you could write a PHP extension that would do this for you. However, to use the extension you'd need to compile your extension and configure PHP to us this extension, which means the portability of your application would be greatly reduced.
No, functions aren't 1st-class citizens so there's no wait = sleep like Javascript for example. You basically have to do what you put in your question:
function wait ($seconds) { sleep($seconds); }
you can use runkit extension
http://us.php.net/manual/en/function.runkit-function-copy.php
function alias($function)
{
return function (/* *args */) use ($function){
return call_user_func_array( $function, func_get_args() );
};
}
$uppercase = alias('strtoupper');
$wait = alias('sleep');
echo $uppercase('hello!'); // -> 'HELLO!'
$wait(1); // -> …
If your PHP doesn't support use x as y syntax, in older PHP version you can define anonymous function:
$wait = create_function('$seconds', 'sleep($seconds);');
$wait(1);
Or place the code inside the constant, e.g.:
define('wait', 'sleep(1);');
eval(wait);
See also: What can I use instead of eval()?
This is especially useful if you've long piece of code, and you don't want to repeat it or the code is not useful for a new function either.
There is also function posted by Dave H which is very useful for creating an alias of a user function:
function create_function_alias($function_name, $alias_name)
{
if(function_exists($alias_name))
return false;
$rf = new ReflectionFunction($function_name);
$fproto = $alias_name.'(';
$fcall = $function_name.'(';
$need_comma = false;
foreach($rf->getParameters() as $param)
{
if($need_comma)
{
$fproto .= ',';
$fcall .= ',';
}
$fproto .= '$'.$param->getName();
$fcall .= '$'.$param->getName();
if($param->isOptional() && $param->isDefaultValueAvailable())
{
$val = $param->getDefaultValue();
if(is_string($val))
$val = "'$val'";
$fproto .= ' = '.$val;
}
$need_comma = true;
}
$fproto .= ')';
$fcall .= ')';
$f = "function $fproto".PHP_EOL;
$f .= '{return '.$fcall.';}';
eval($f);
return true;
}
nope. the way you wrote is the best way to do it.
No, there's no quick way to do so - at least for anything before PHP v5.3, and it's not a particularly good idea to do so either. It simply complicates matters.
Since PHP 5.6
This is especially helpful for use in classes with magic methods.
class User extends SomethingWithMagicMethods {
public function Listings(...$args) {
return $this->Children(...$args);
}
}
But I'm pretty sure it works with regular functions too.
function UserListings(...$args) {
return UserChildren(...$args);
}
Source:
PHP: New features -> "Variadic functions via ..."
I know this is old, but you can always
$wait = 'sleep';
$wait();
What I have used in my CLASS
function __call($name, $args) {
$alias['execute']=array('done','finish');
$alias['query']=array('prepare','do');
if (in_array($name,$alias['execute'])){
call_user_func_array("execute",$args);
return TRUE;
}elseif(in_array($name,$alias['query'])){
call_user_func_array("query",$args);
return TRUE;
}
die($this->_errors.' Invalid method:'.$name.PHP_EOL);
}
Related
I have four methods which alter the input and return the output.
class edit
{
function a($input) { return $input + 4; }
function b($input) { return $input - 2; }
function c($input) { return $input * 10; }
function d($input) { return $input / 8; }
}
Coincidentally these methods need to be called one after the other with the returned output from the previous as the input to the next.
We can handle this process multiple ways.
$handle = new edit();
$output = $handle->a(8);
$output = $handle->b($output);
$output = $handle->c($output);
$output = $handle->d($output);
or
create another method within the class to handle this entire procedure.
function all($input)
{
$output = $this->a($input);
$output = $this->b($output);
$output = $this->c($output);
$output = $this->d($output);
return $output;
}
$handle = new edit(8);
$handle->all();
These both achieve the same task.
However, I have recently learned about composition functions, Which is perfect for I need to achieve.
(note for the example here I have moved the methods a,b,c,d from the class and will call them as functions in a procedural manor, I have been unable to make this composition function OOP friendly, please excuse me for this.)
function compose($f,$g,$h,$i)
{
return function($x) use ($f, $g, $h, $i) { return $f($g($h($i($x)))); };
}
$comp = compose('a', 'b','c','d');
$result = $comp(8);
With all this being said, I want to know the benefit of achieving this task with the composition function?
I can only notice minimal improvement in that we do not have to pass the input four times, only once.
In my recent research, I have come across multiple software engineers talking about how great functional programming is.
I feel that I am missing something? Or is the only improvement what I mentioned?
PS - The language I use is PHP, The methods/functions I gave here are just simple examples to illustrate the point. I am also trying to adhere to SOLID principles.
Thanks.
Is there any way to determine whether FirePHP is installed on the server (via PEAR)? I'd like to make possible logging in FirePHP but also not to crash the code for everyone without that tool.
The example, how I imagine it should work:
$message = "hello";
function log($message) {
if (library_exists('FirePHPCore/fb.php')) {
require_once('FirePHPCore/fb.php');
ob_start();
\FB::log($message);
} else {
SomeBoringLogger::log($message);
}
}
I haven't found anything like my library_exists method. Is there anything like that in PHP?
#include_once('FirePHPCore/fb.php'); // Ignore any errors here, as we check for existance
if (class_exists('FirePHP')) { // Do something after this
http://php.net/manual/en/function.class-exists.php
FirePHP uses FirePHP as its class name, so if it is available, that class should be defined
For PHP 5.3.2 or later, use zerkms's suggestion:
(!stream_resolve_include_path('FirePHPCore/fb.php')===FALSE)
Use include_once, so it doesn't kill the request. As #Brad suggests, use class_exists afterwards.
$message = "hello";
safe_include_once('FirePHPCore/fb.php');
if (class_exists('FB')) {
function log($message) {
//using FirePHP
}
} else {
function log($message) {
SomeBoringLogger::log($message);
}
}
function safe_include_once($path) {
if ($path = stream_resolve_include_path($path)) {
include_once($path);
}
}
[Edit] Using stream_resolve_include_path in safe_include_path.
[Edit2] Faster runtime logging.
file_exists() can be used for your case.
Here's the code for my original PHP code:
public function outputText() {
$i = 1;
foreach($this->sorted_data as $this->data) {
echo "$i. ".$this->data[0]."<br/>";
$i++;
}
}
And here's the code for the PHPUnit:
public function testVerify() {
$yn = new SortThisData();
$yn->readFile("input.txt");
$output = $yn->outputText();
$this->assertTrue(is_string($output));
//if(!is_string($yn->get()))
// return false;
//$this->assertNotEmpty($yn->get());
}
The class is called SortThisData in the original PHP file.
When I used gettype(), it said it was null. I'm trying to verify that it is a string so it can pass in PHPUnit. Is there a way I can do this?
You're looking for assertInternalType().
Update: I didn't realize you were echoing the output. You will probably need to use output buffering to capture the text.
public function testVerify() {
$yn = new SortThisData();
$yn->readFile("input.txt");
// start output buffering and capture the output
ob_start();
$yn->outputText();
$output = ob_get_clean();
$this->assertInternalType('string', $output);
}
No disagreement with Baylor's answer. To answer the question, as asked, what you had was also good enough:
$this->assertTrue(is_string($output));
Or you could have done:
$this->assertEquals('string',gettype($output));
(The advantage of the latter is, when it fails, it will also tell you the type of $output; assertTrue will only tell you that something failed.)
assertInternalType() does exactly that, but was only introduced in PHPUnit 3.5, and you will still find PHPUnit 3.4 in use on some machines.
Take a look at the following illustration:
// Trims input, fixes spaces and encodes bad glyphs. Also works with arrays.
function prepare_param($param)
{
$retval = "";
function prc($param)
{
$r = split(" ", trim($param));
foreach($r as $i => $e)
$r[$i] = urlencode($e);
return join("+", $r);
}
// If input is an array
if(is_array($param))
{
$retval = array();
foreach($param as $e)
$retval[] = prc($e);
}
// If input is a string
else if(is_string($param))
{
return prc($param);
}
else throw new Exception("Invalid input! Expected String or Array.");
}
Obviously the function prc will now be declared globally, even though declared inside a function. Is there a way to follow this principle, creating a tiny function/macro inside another function as not to litter the global scope? The alternative would be to make a class with a private function, which seems like overkill for my use.
Any help appreciated
You probably want closures, which are anonymous functions.
If you have PHP 5.3, enter anonymous functions:
$prc = function($param)
{
$r = split(" ", trim($param));
foreach($r as $i => $e)
$r[$i] = urlencode($e);
return join("+", $r);
};
if(is_array($param))
{
$retval = array();
foreach($param as $e)
$retval[] = $prc($e);
}
else if(is_string($param))
{
return $prc($param);
}
In this case, $prc only lives in the scope of your prepare_param() function.
If you have access to >=PHP 5.3, you can use anonymous functions, and if not, you can use create_function.
If you don't have PHP 5.3, you can use the create_function function.
There are two ways to do so. The closures/anonymous functions are possible from PHP 5.3, and the oldschool way would be to use create_function() - which is quite fugly.
However in your case, you don't want either. There is no benefit in creating or recreating the function. You just need it once, as it does not depend on any initialization state. The idiom you should use is called "dererred definition" and possible in PHP with:
if (!function_exists("prc")) {
function prc($param) {
...
}
}
You should name it with its parent function as prefix however (e.g. prepare__prc) to avoid clashes and to signalize its internal use.
Oh, and btw it could also be simplified compacted into:
$param = join("+", array_map("urlencode", split(" ", trim($param))));
anonymous functions might be what you are looking for
<?php
$greet = function($name)
{
printf("Hello %s\r\n", $name);
};
$greet('World');
$greet('PHP');
?>
If you don't use php 5.3 please be aware of the fact that the memory allocated by the "create_function()" function isn't released until the php process finishes. So if you create a lot of functions you might be running into issues.
How are callbacks written in PHP?
The manual uses the terms "callback" and "callable" interchangeably, however, "callback" traditionally refers to a string or array value that acts like a function pointer, referencing a function or class method for future invocation. This has allowed some elements of functional programming since PHP 4. The flavors are:
$cb1 = 'someGlobalFunction';
$cb2 = ['ClassName', 'someStaticMethod'];
$cb3 = [$object, 'somePublicMethod'];
// this syntax is callable since PHP 5.2.3 but a string containing it
// cannot be called directly
$cb2 = 'ClassName::someStaticMethod';
$cb2(); // fatal error
// legacy syntax for PHP 4
$cb3 = array(&$object, 'somePublicMethod');
This is a safe way to use callable values in general:
if (is_callable($cb2)) {
// Autoloading will be invoked to load the class "ClassName" if it's not
// yet defined, and PHP will check that the class has a method
// "someStaticMethod". Note that is_callable() will NOT verify that the
// method can safely be executed in static context.
$returnValue = call_user_func($cb2, $arg1, $arg2);
}
Modern PHP versions allow the first three formats above to be invoked directly as $cb(). call_user_func and call_user_func_array support all the above.
See: http://php.net/manual/en/language.types.callable.php
Notes/Caveats:
If the function/class is namespaced, the string must contain the fully-qualified name. E.g. ['Vendor\Package\Foo', 'method']
call_user_func does not support passing non-objects by reference, so you can either use call_user_func_array or, in later PHP versions, save the callback to a var and use the direct syntax: $cb();
Objects with an __invoke() method (including anonymous functions) fall under the category "callable" and can be used the same way, but I personally don't associate these with the legacy "callback" term.
The legacy create_function() creates a global function and returns its name. It's a wrapper for eval() and anonymous functions should be used instead.
With PHP 5.3, you can now do this:
function doIt($callback) { $callback(); }
doIt(function() {
// this will be done
});
Finally a nice way to do it. A great addition to PHP, because callbacks are awesome.
Implementation of a callback is done like so
// This function uses a callback function.
function doIt($callback)
{
$data = "this is my data";
$callback($data);
}
// This is a sample callback function for doIt().
function myCallback($data)
{
print 'Data is: ' . $data . "\n";
}
// Call doIt() and pass our sample callback function's name.
doIt('myCallback');
Displays: Data is: this is my data
One nifty trick that I've recently found is to use PHP's create_function() to create an anonymous/lambda function for one-shot use. It's useful for PHP functions like array_map(), preg_replace_callback(), or usort() that use callbacks for custom processing. It looks pretty much like it does an eval() under the covers, but it's still a nice functional-style way to use PHP.
well... with 5.3 on the horizon, all will be better, because with 5.3, we'll get closures and with them anonymous functions
http://wiki.php.net/rfc/closures
You will want to verify whatever your calling is valid. For example, in the case of a specific function, you will want to check and see if the function exists:
function doIt($callback) {
if(function_exists($callback)) {
$callback();
} else {
// some error handling
}
}
create_function did not work for me inside a class. I had to use call_user_func.
<?php
class Dispatcher {
//Added explicit callback declaration.
var $callback;
public function Dispatcher( $callback ){
$this->callback = $callback;
}
public function asynchronous_method(){
//do asynch stuff, like fwrite...then, fire callback.
if ( isset( $this->callback ) ) {
if (function_exists( $this->callback )) call_user_func( $this->callback, "File done!" );
}
}
}
Then, to use:
<?php
include_once('Dispatcher.php');
$d = new Dispatcher( 'do_callback' );
$d->asynchronous_method();
function do_callback( $data ){
print 'Data is: ' . $data . "\n";
}
?>
[Edit]
Added a missing parenthesis.
Also, added the callback declaration, I prefer it that way.
For those who don't care about breaking compatibility with PHP < 5.4, I'd suggest using type hinting to make a cleaner implementation.
function call_with_hello_and_append_world( callable $callback )
{
// No need to check $closure because of the type hint
return $callback( "hello" )."world";
}
function append_space( $string )
{
return $string." ";
}
$output1 = call_with_hello_and_append_world( function( $string ) { return $string." "; } );
var_dump( $output1 ); // string(11) "hello world"
$output2 = call_with_hello_and_append_world( "append_space" );
var_dump( $output2 ); // string(11) "hello world"
$old_lambda = create_function( '$string', 'return $string." ";' );
$output3 = call_with_hello_and_append_world( $old_lambda );
var_dump( $output3 ); // string(11) "hello world"
I cringe every time I use create_function() in php.
Parameters are a coma separated string, the whole function body in a string... Argh... I think they could not have made it uglier even if they tried.
Unfortunately, it is the only choice when creating a named function is not worth the trouble.