-
Notifications
You must be signed in to change notification settings - Fork 831
Improve documentation on callables #4752
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -30,10 +30,18 @@ | |
| <para> | ||
| A method of an instantiated <type>object</type> is passed as an | ||
| <type>array</type> containing an <type>object</type> at index 0 and the | ||
| method name at index 1. Accessing protected and private methods from | ||
| within a class is allowed. | ||
| method name at index 1. Passing protected and private methods | ||
| with the <type>callable</type> syntax is allowed. | ||
| </para> | ||
|
|
||
| <note> | ||
| <para> | ||
| If a callable of a protected or a private method is invoked from outside the class | ||
| with no visibility of said methods (e.g. being called from a POSIX signal handler), | ||
| a runtime error is thrown because the callable is invalid at the time of invocation. | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What kind of error?
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think this means what you wanted to say. A callable or a closure of a private member can be invoked from outside the class. The problem is only with the pseudo-callables in the form of array which are converted into the actual closure at the invokation time only and therefore refer to an inaccessible member. This page should probably be entirely rewritten to explain the modern concepts better. |
||
| </para> | ||
| </note> | ||
|
|
||
| <para> | ||
| Static class methods can also be passed without instantiating an | ||
| <type>object</type> of that class by either, passing the class name | ||
|
|
@@ -156,6 +164,80 @@ print implode(' ', $new_numbers); | |
| </example> | ||
| </para> | ||
|
|
||
| <para> | ||
| <example> | ||
| <title> | ||
| Manually invoking callbacks | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is that the appropriate title here? The example feels a big long and involved, but I don't quite know what it's trying to demonstrate. |
||
| </title> | ||
| <programlisting role="php"> | ||
| <![CDATA[ | ||
| <?php | ||
|
|
||
| // define a callback handler that executes the callable (no parameters) | ||
| function invokeCallback(callable $theCallback) { | ||
| $theCallback(); | ||
| } | ||
|
|
||
| // prints "42" | ||
| invokeCallback(function () { | ||
| echo "42" . PHP_EOL; | ||
| }); | ||
|
|
||
| // define a callback handler that executes the callable with a parameter | ||
| function processNumber(callable $processor, int $theNumber) { | ||
| // process a number, and print its result | ||
| $result = $processor($theNumber); | ||
| echo $result . PHP_EOL; | ||
| } | ||
|
|
||
| // prints "72" | ||
| processNumber(fn ($x) => $x * 3, 24); | ||
|
|
||
| // define a class implementing the __invoke method | ||
| class NumberTripler | ||
| { | ||
| public function __invoke($x) | ||
| { | ||
| return $x * 3; | ||
| } | ||
| } | ||
|
|
||
| // prints "15" | ||
| $tripler = new NumberTripler(); | ||
| processNumber($tripler, 5); | ||
|
|
||
| // define a class with a private instance method, to be called with the callable syntax | ||
| class HiddenFactory | ||
| { | ||
| private function hiddenWork() | ||
| { | ||
| echo "256" . PHP_EOL; | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please don't use
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Uh, what? No,
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It creates inconsistent output on different platforms and could confuse new users. The standard |
||
| } | ||
|
|
||
| public function getProof() | ||
| { | ||
| return Closure::fromCallable([$this, 'hiddenWork']); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Using |
||
| } | ||
| } | ||
|
|
||
| // prints "256" | ||
| $factory = new HiddenFactory(); | ||
| $theProof = $factory->getProof(); | ||
| invokeCallback($theProof); | ||
| ?> | ||
| </programlisting> | ||
| &example.outputs; | ||
| <screen> | ||
| <![CDATA[ | ||
| 42 | ||
| 72 | ||
| 15 | ||
| 256 | ||
| ]]> | ||
| </screen> | ||
| </example> | ||
| </para> | ||
|
|
||
| ¬e.func-callback-exceptions; | ||
| </sect2> | ||
|
|
||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A POSIX signal handler is a very niche example here. I know it's the one that prompted this PR, but I'd use something more common or self-evident.