<?php
include_once $_SERVER['DOCUMENT_ROOT'] . '/include/shared-manual.inc';
$TOC = array();
$TOC_DEPRECATED = array();
$PARENTS = array();
include_once dirname(__FILE__) ."/toc/language.functions.inc";
$setup = array (
  'home' => 
  array (
    0 => 'index.php',
    1 => 'PHP Manual',
  ),
  'head' => 
  array (
    0 => 'UTF-8',
    1 => 'uk',
  ),
  'this' => 
  array (
    0 => 'functions.first_class_callable_syntax.php',
    1 => 'First class callable syntax',
    2 => 'First class callable syntax',
  ),
  'up' => 
  array (
    0 => 'language.functions.php',
    1 => 'Functions',
  ),
  'prev' => 
  array (
    0 => 'functions.arrow.php',
    1 => 'Arrow Functions',
  ),
  'next' => 
  array (
    0 => 'language.oop5.php',
    1 => 'Класи та об\'єкти',
  ),
  'alternatives' => 
  array (
  ),
  'source' => 
  array (
    'lang' => 'en',
    'path' => 'language/functions.xml',
  ),
  'history' => 
  array (
  ),
);
$setup["toc"] = $TOC;
$setup["toc_deprecated"] = $TOC_DEPRECATED;
$setup["parents"] = $PARENTS;
manual_setup($setup);

contributors($setup);

?>
<div id="functions.first_class_callable_syntax" class="sect1">
   <h2 class="title">First class callable syntax</h2>

   <p class="para">
    The first class callable syntax is introduced as of PHP 8.1.0, as a way of creating <a href="functions.anonymous.php" class="link">anonymous functions</a> from <a href="language.types.callable.php" class="link">callable</a>.
    It supersedes existing callable syntax using strings and arrays.
    The advantage of this syntax is that it is accessible to static analysis, and uses the scope at the point where the callable is acquired.
   </p>

   <p class="para">
    <code class="code">CallableExpr(...)</code> syntax is used to create a <span class="classname"><a href="class.closure.php" class="classname">Closure</a></span> object from callable. <code class="code">CallableExpr</code> accepts any expression that can be directly called in the PHP grammar:
    <div class="example" id="example-1">
     <p><strong>Приклад #1 Simple first class callable syntax</strong></p>
     <div class="example-contents">
<div class="phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /><br /></span><span style="color: #007700">class </span><span style="color: #0000BB">Foo </span><span style="color: #007700">{<br />   public function </span><span style="color: #0000BB">method</span><span style="color: #007700">() {}<br />   public static function </span><span style="color: #0000BB">staticmethod</span><span style="color: #007700">() {}<br />   public function </span><span style="color: #0000BB">__invoke</span><span style="color: #007700">() {}<br />}<br /><br /></span><span style="color: #0000BB">$obj </span><span style="color: #007700">= new </span><span style="color: #0000BB">Foo</span><span style="color: #007700">();<br /></span><span style="color: #0000BB">$classStr </span><span style="color: #007700">= </span><span style="color: #DD0000">'Foo'</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">$methodStr </span><span style="color: #007700">= </span><span style="color: #DD0000">'method'</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">$staticmethodStr </span><span style="color: #007700">= </span><span style="color: #DD0000">'staticmethod'</span><span style="color: #007700">;<br /><br /><br /></span><span style="color: #0000BB">$f1 </span><span style="color: #007700">= </span><span style="color: #0000BB">strlen</span><span style="color: #007700">(...);<br /></span><span style="color: #0000BB">$f2 </span><span style="color: #007700">= </span><span style="color: #0000BB">$obj</span><span style="color: #007700">(...);  </span><span style="color: #FF8000">// invokable object<br /></span><span style="color: #0000BB">$f3 </span><span style="color: #007700">= </span><span style="color: #0000BB">$obj</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">method</span><span style="color: #007700">(...);<br /></span><span style="color: #0000BB">$f4 </span><span style="color: #007700">= </span><span style="color: #0000BB">$obj</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">$methodStr</span><span style="color: #007700">(...);<br /></span><span style="color: #0000BB">$f5 </span><span style="color: #007700">= </span><span style="color: #0000BB">Foo</span><span style="color: #007700">::</span><span style="color: #0000BB">staticmethod</span><span style="color: #007700">(...);<br /></span><span style="color: #0000BB">$f6 </span><span style="color: #007700">= </span><span style="color: #0000BB">$classStr</span><span style="color: #007700">::</span><span style="color: #0000BB">$staticmethodStr</span><span style="color: #007700">(...);<br /><br /></span><span style="color: #FF8000">// traditional callable using string, array<br /></span><span style="color: #0000BB">$f7 </span><span style="color: #007700">= </span><span style="color: #DD0000">'strlen'</span><span style="color: #007700">(...);<br /></span><span style="color: #0000BB">$f8 </span><span style="color: #007700">= [</span><span style="color: #0000BB">$obj</span><span style="color: #007700">, </span><span style="color: #DD0000">'method'</span><span style="color: #007700">](...);<br /></span><span style="color: #0000BB">$f9 </span><span style="color: #007700">= [</span><span style="color: #0000BB">Foo</span><span style="color: #007700">::class, </span><span style="color: #DD0000">'staticmethod'</span><span style="color: #007700">](...);<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
     </div>

    </div>
   </p>

   <blockquote class="note"><p><strong class="note">Зауваження</strong>: 
    <p class="para">
      The <code class="code">...</code> is part of the syntax, and not an omission.
    </p>
   </p></blockquote>

   <p class="para">
    <code class="code">CallableExpr(...)</code> has the same semantics as <span class="methodname"><a href="closure.fromcallable.php" class="methodname">Closure::fromCallable()</a></span>.
    That is, unlike callable using strings and arrays, <code class="code">CallableExpr(...)</code> respects the scope at the point where it is created:
    <div class="example" id="example-2">
     <p><strong>Приклад #2 Scope comparison of <code class="code">CallableExpr(...)</code> and traditional callable</strong></p>
     <div class="example-contents">
<div class="phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /><br /></span><span style="color: #007700">class </span><span style="color: #0000BB">Foo </span><span style="color: #007700">{<br />    public function </span><span style="color: #0000BB">getPrivateMethod</span><span style="color: #007700">() {<br />        return [</span><span style="color: #0000BB">$this</span><span style="color: #007700">, </span><span style="color: #DD0000">'privateMethod'</span><span style="color: #007700">];<br />    }<br /><br />    private function </span><span style="color: #0000BB">privateMethod</span><span style="color: #007700">() {<br />        echo </span><span style="color: #0000BB">__METHOD__</span><span style="color: #007700">, </span><span style="color: #DD0000">"\n"</span><span style="color: #007700">;<br />    }<br />}<br /><br /></span><span style="color: #0000BB">$foo </span><span style="color: #007700">= new </span><span style="color: #0000BB">Foo</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">$privateMethod </span><span style="color: #007700">= </span><span style="color: #0000BB">$foo</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">getPrivateMethod</span><span style="color: #007700">();<br /></span><span style="color: #0000BB">$privateMethod</span><span style="color: #007700">();<br /></span><span style="color: #FF8000">// Fatal error: Call to private method Foo::privateMethod() from global scope<br />// This is because call is performed outside from Foo and visibility will be checked from this point.<br /><br /></span><span style="color: #007700">class </span><span style="color: #0000BB">Foo1 </span><span style="color: #007700">{<br />    public function </span><span style="color: #0000BB">getPrivateMethod</span><span style="color: #007700">() {<br />        </span><span style="color: #FF8000">// Uses the scope where the callable is acquired.<br />        </span><span style="color: #007700">return </span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">privateMethod</span><span style="color: #007700">(...); </span><span style="color: #FF8000">// identical to Closure::fromCallable([$this, 'privateMethod']);<br />    </span><span style="color: #007700">}<br /><br />    private function </span><span style="color: #0000BB">privateMethod</span><span style="color: #007700">() {<br />        echo </span><span style="color: #0000BB">__METHOD__</span><span style="color: #007700">, </span><span style="color: #DD0000">"\n"</span><span style="color: #007700">;<br />    }<br />}<br /><br /></span><span style="color: #0000BB">$foo1 </span><span style="color: #007700">= new </span><span style="color: #0000BB">Foo1</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">$privateMethod </span><span style="color: #007700">= </span><span style="color: #0000BB">$foo1</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">getPrivateMethod</span><span style="color: #007700">();<br /></span><span style="color: #0000BB">$privateMethod</span><span style="color: #007700">();  </span><span style="color: #FF8000">// Foo1::privateMethod<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
     </div>

    </div>

   </p>

   <blockquote class="note"><p><strong class="note">Зауваження</strong>: 
    <p class="para">
     Object creation by this syntax (e.g <code class="code">new Foo(...)</code>) is not supported, because <code class="code">new Foo()</code> syntax is not considered a call.
    </p>
   </p></blockquote>

   <blockquote class="note"><p><strong class="note">Зауваження</strong>: 
    <p class="para">
     The first-class callable syntax cannot be combined with the <a href="language.oop5.basic.php#language.oop5.basic.nullsafe" class="link">nullsafe operator</a>. Both of the following result in a compile-time error:
     <div class="informalexample">
      <div class="example-contents">
<div class="phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br />$obj</span><span style="color: #007700">?-&gt;</span><span style="color: #0000BB">method</span><span style="color: #007700">(...);<br /></span><span style="color: #0000BB">$obj</span><span style="color: #007700">?-&gt;</span><span style="color: #0000BB">prop</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">method</span><span style="color: #007700">(...);<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
      </div>

     </div>
    </p>
   </p></blockquote>
  </div><?php manual_footer($setup); ?>