I noticed two important thing about putting callbacks into an arg list when calling a function:
1. The function to which the callback refers must be defined earlier in the source stream. So for example:
function main() {...; usort($array, 'sortfunction'); ... }
function sortfunction($a, $b){ return 0; }
Will NOT work, but this will:
function sortfunction($a, $b){ return 0; }
function main() {...; usort($array, 'sortfunction'); ... }
2. It's not really just a string. For example, this doesn't work:
usort($array, ($reverse?'reversesorter':'forwardsorter'));
I found these two discoveries quite counterintuitive.
شبه نوعها و متغیرهای استفاده شده در این مستندات
mixed
mixed نشاندهنده قبول نمودن چندین نوع پارامتر (البته نه همه) است.
gettype() برای مثال تمام انواع PHP را خواهد پذیرفت در حالی که str_replace() تنها string و array را خواهد پذیرفت.
callback
بعضی توابع مانند call_user_func() یا usort() توابع فراخوانی بازگشتی را به عنوان پارامتر قبول مینمایند. توابع فراخوانی بازگشتی نمیتوانند توابع ساده باشند اما متدهای object شامل متدهای استاتیک کلاس است.
یک تابع PHP با استفاده از نام آن به عنوان یکstring استفاده میشود. یک تابع تعریف شده توسط کاربر و داخلی استفاده شده است به جز ساختهای زبانی array()٬ echo()٬ empty()٬ eval()٬ exit()٬ isset()٬ list()٬ print() یا unset().
یک متد object نمونهسازی شده به عنوان یک array شامل object در اندیس 0 و نام متد در اندیس 1 است.
متدهای استاتیک کلاس بدون قرار دادن مقدار اولیه object از یک کلاس با استفاده از گذراندن نام کلاس به جای object در اندیس 0 ممکن است.
جدا از توابع تعریف شده معمول توسط کاربر create_function() نیز میتواند یک تابع فراخوانی بازگشتی ناشناس بوجود آورد.از PHP 5.3.0 امکان ارسال closure به یک پارامتر بازگشتی وجود دارد.
Example #1 نمونه توابع فراخوانی بازگشتی
<?php
// An example callback function
function my_callback_function() {
echo 'hello world!';
}
// An example callback method
class MyClass {
static function myCallbackMethod() {
echo 'Hello World!';
}
}
// Type 1: Simple callback
call_user_func('my_callback_function');
// Type 2: Static class method call
call_user_func(array('MyClass', 'myCallbackMethod'));
// Type 3: Object method call
$obj = new MyClass();
call_user_func(array($obj, 'myCallbackMethod'));
// Type 4: Static class method call (As of PHP 5.2.3)
call_user_func('MyClass::myCallbackMethod');
// Type 5: Relative static class method call (As of PHP 5.3.0)
class A {
public static function who() {
echo "A\n";
}
}
class B extends A {
public static function who() {
echo "B\n";
}
}
call_user_func(array('B', 'parent::who')); // A
?>
Example #2 Callback example using a Closure
<?php
// Our closure
$double = function($a) {
return $a * 2;
};
// This is our range of numbers
$numbers = range(1, 5);
// Use the closure as a callback here to
// double the size of each element in our
// range
$new_numbers = array_map($double, $numbers);
print implode(' ', $new_numbers);
?>
The above example will output:
2 4 6 8 10
Note: در PHP4 لازم بود از مرجع برای ساخت نمونه فراخوانی اشارهگر به object حقیقی و نه کپی آن استفاده شود. برای جزئیات بیشتر مرجعها توضیج داده شده را ببینید.
void
void به عنوان نوع بازگشتی به معنای بیفایده بودن بازگشت است. void در یک لیست پارامتر به معنای عدم پذیریش پارامتر توسط تابع است.
...
$... در نمونه تابع به معنای و همینطور در ادامه است. نام این متغیر هنگامی استفاده میشود که تابع قادر به دریافت هر تعداد آرگومات است.
The documentation is a little confusing, and with the recent OO changes it adds a little more to the confusion.
I was curious whether you could pass an object through the user func, modify it in that callback and have the actual object updated or whether some cloning was going on behind the scenes.
<?php
class Test
{
var $sValue = 'abc';
function testing($objTest)
{
$objTest->sValue = '123';
}
}
$obj = new Test();
call_user_func(array($obj, 'testing'), $obj);
var_dump($obj);
?>
This works as expected: The object is not cloned, and $sValue is properly set to '123'. With the OO changes in PHP 5, you don't need to do "function testing(&$objTest)" as it is already passed by reference.
An example with PHP 5.3 and lambda functions
<?php
array_map (function ($value) {
return new MyFormElement ($value);
}, $_POST);
?>
Parent methods for callbacks should be called 'parent::method', so if you wish to call a non-static parent method via a callback, you should use a callback of
<?
// always works
$callback = array($this, 'parent::method')
// works but gives an error in PHP5 with E_STRICT if the parent method is not static
$callback array('parent', 'method');
?>
The mixed pseudotype is explained as meaning "multiple but not necessarily all" types, and the example of str_replace(mixed, mixed, mixed) is given where "mixed" means "string or array".
Keep in mind that this refers to the types of the function's arguments _after_ any type juggling.
If you pass a string as the callback function (i.e., 2nd parm to preg_replace_callback()), then PHP will interpret it as a function's name in the current scope -- and Main::dada_cb is not a valid function name in any scope.
If you want to specify a static method of a class as the callback (i.e., "Main::dada_cb"), then you must pass as 2nd parm to preg_replace_callback:
array( 'Main', 'dada_cb')
And, if you want to use as a callback some method of an instantiated object (i.e., $object->dada_cb), then you must pass as the 2nd parm to preg_replace_callback:
array( $object, 'dada_cb' )
To recap mr dot lilov at gmail dot com's comment: If you want to pass a function as an argument to another function, for example "array_map", do this:
regular functions:
<?
array_map(intval, $array)
?>
static functions in a class:
<?
array_map(array('MyClass', 'MyFunction'), $array)
?>
functions from an object:
<?
array_map(array($this, 'MyFunction'), $array)
?>
I hope this clarifies things a little bit
Note that (e.g.) usort calls on static methods of classes in a namespace need to be laid out as follows:
usort($arr, array('\Namespace\ClassName', 'functionName'));
