<?php
include_once $_SERVER['DOCUMENT_ROOT'] . '/include/shared-manual.inc';
$TOC = array();
$TOC_DEPRECATED = array();
$PARENTS = array();
include_once dirname(__FILE__) ."/toc/language.operators.inc";
$setup = array (
  'home' => 
  array (
    0 => 'index.php',
    1 => 'PHP Manual',
  ),
  'head' => 
  array (
    0 => 'UTF-8',
    1 => 'zh',
  ),
  'this' => 
  array (
    0 => 'language.operators.functional.php',
    1 => '函数式',
    2 => '函数式运算符',
  ),
  'up' => 
  array (
    0 => 'language.operators.php',
    1 => '运算符',
  ),
  'prev' => 
  array (
    0 => 'language.operators.type.php',
    1 => '类型',
  ),
  'next' => 
  array (
    0 => 'language.control-structures.php',
    1 => '流程控制',
  ),
  'alternatives' => 
  array (
  ),
  'source' => 
  array (
    'lang' => 'zh',
    'path' => 'language/operators/functional.xml',
  ),
  'history' => 
  array (
  ),
);
$setup["toc"] = $TOC;
$setup["toc_deprecated"] = $TOC_DEPRECATED;
$setup["parents"] = $PARENTS;
manual_setup($setup);

contributors($setup);

?>
<div id="language.operators.functional" class="sect1">
 <h2 class="title">函数式运算符</h2>
 
 <p class="para">
  PHP 8.5 及更高版本支持可直接作用于可调用对象的操作符。<code class="literal">|&gt;</code>
  操作符（或称为“管道”），在右侧接受单个参数的可调用对象，并将左侧的值传递给它，最终返回该可调用对象的结果。右侧的可调用对象可以是任何有效的
  PHP 可调用对象：<span class="classname"><a href="class.closure.php" class="classname">Closure</a></span>、<a href="functions.first_class_callable_syntax.php" class="link">一等可调用对象</a>、实现了 <a href="language.oop5.magic.php#object.invoke" class="link">__invoke()</a> 方法的对象等。
 </p>
 <p class="para">
  这意味着以下两行在逻辑上是等价的。
  <div class="example" id="example-1">
   <p><strong>示例 #1 使用 <code class="literal">|&gt;</code></strong></p>
   <div class="example-contents">
<div class="annotation-interactive phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br />$result </span><span style="color: #007700">= </span><span style="color: #DD0000">"Hello World" </span><span style="color: #007700">|&gt; </span><span style="color: #0000BB">strlen</span><span style="color: #007700">(...);<br />echo </span><span style="color: #0000BB">$result</span><span style="color: #007700">, </span><span style="color: #0000BB">PHP_EOL</span><span style="color: #007700">;<br /><br /></span><span style="color: #0000BB">$result </span><span style="color: #007700">= </span><span style="color: #0000BB">strlen</span><span style="color: #007700">(</span><span style="color: #DD0000">"Hello World"</span><span style="color: #007700">);<br />echo </span><span style="color: #0000BB">$result</span><span style="color: #007700">, </span><span style="color: #0000BB">PHP_EOL</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
   </div>

   <div class="example-contents"><p>以上示例会输出：</p></div>
   <div class="example-contents screen">
<div class="annotation-interactive cdata"><pre>
11
11
</pre></div>
   </div>
  </div>
 </p>
 <p class="para">
  对于单次调用，并不特别有用。当多个调用链式组合时，其作用才得以体现。也就是说，以下两段代码在逻辑上是等价的：
  <div class="example" id="example-2">
   <p><strong>示例 #2 链式 |&gt; 调用</strong></p>
   <div class="example-contents">
<div class="annotation-interactive phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br />$result </span><span style="color: #007700">= </span><span style="color: #DD0000">"PHP Rocks"<br />    </span><span style="color: #007700">|&gt; </span><span style="color: #0000BB">htmlentities</span><span style="color: #007700">(...)<br />    |&gt; </span><span style="color: #0000BB">str_split</span><span style="color: #007700">(...)<br />    |&gt; (fn(</span><span style="color: #0000BB">$x</span><span style="color: #007700">) =&gt; </span><span style="color: #0000BB">array_map</span><span style="color: #007700">(</span><span style="color: #0000BB">strtoupper</span><span style="color: #007700">(...), </span><span style="color: #0000BB">$x</span><span style="color: #007700">))<br />    |&gt; (fn(</span><span style="color: #0000BB">$x</span><span style="color: #007700">) =&gt; </span><span style="color: #0000BB">array_filter</span><span style="color: #007700">(</span><span style="color: #0000BB">$x</span><span style="color: #007700">, fn(</span><span style="color: #0000BB">$v</span><span style="color: #007700">) =&gt; </span><span style="color: #0000BB">$v </span><span style="color: #007700">!= </span><span style="color: #DD0000">'O'</span><span style="color: #007700">))<br />;<br /></span><span style="color: #0000BB">print_r</span><span style="color: #007700">(</span><span style="color: #0000BB">$result</span><span style="color: #007700">);<br /><br /></span><span style="color: #0000BB">$temp </span><span style="color: #007700">= </span><span style="color: #DD0000">"PHP Rocks"</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">$temp </span><span style="color: #007700">= </span><span style="color: #0000BB">htmlentities</span><span style="color: #007700">(</span><span style="color: #0000BB">$temp</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">$temp </span><span style="color: #007700">= </span><span style="color: #0000BB">str_split</span><span style="color: #007700">(</span><span style="color: #0000BB">$temp</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">$temp </span><span style="color: #007700">= </span><span style="color: #0000BB">array_map</span><span style="color: #007700">(</span><span style="color: #0000BB">strtoupper</span><span style="color: #007700">(...), </span><span style="color: #0000BB">$temp</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">$temp </span><span style="color: #007700">= </span><span style="color: #0000BB">array_filter</span><span style="color: #007700">(</span><span style="color: #0000BB">$temp</span><span style="color: #007700">, fn(</span><span style="color: #0000BB">$v</span><span style="color: #007700">) =&gt; </span><span style="color: #0000BB">$v </span><span style="color: #007700">!= </span><span style="color: #DD0000">'O'</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">$result </span><span style="color: #007700">= </span><span style="color: #0000BB">$temp</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">print_r</span><span style="color: #007700">(</span><span style="color: #0000BB">$result</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
   </div>

   <div class="example-contents"><p>以上示例会输出：</p></div>
   <div class="example-contents screen">
<div class="annotation-interactive cdata"><pre>
Array
(
    [0] =&gt; P
    [1] =&gt; H
    [2] =&gt; P
    [3] =&gt;
    [4] =&gt; R
    [6] =&gt; C
    [7] =&gt; K
    [8] =&gt; S
)
Array
(
    [0] =&gt; P
    [1] =&gt; H
    [2] =&gt; P
    [3] =&gt;
    [4] =&gt; R
    [6] =&gt; C
    [7] =&gt; K
    [8] =&gt; S
)
</pre></div>
   </div>
  </div>
 </p>
 <p class="para">
  管道的左侧可以是任何值或表达式。右侧可以是任何接受单个参数的有效 PHP
  可调用对象，或是任何能够解析为这种可调用对象的表达式。不允许超过一个必需参数的函数，此类情况将如同普通调用时参数不足一样导致失败。不允许通过引用传递变量的函数。如果右侧无法解析为有效的可调用对象，则会抛出 Error。
 </p>
 <blockquote class="note"><p><strong class="note">注意</strong>: 
  <p class="para">
   需要注意，为了避免语法歧义，<a href="functions.arrow.php" class="link">箭头函数</a>在与管道操作符一起使用时必须用括号包裹，如上述示例所示。未遵循此要求将导致核心错误。
  </p>
 </p></blockquote>

 <div class="sect2">
  <h3 class="title">参见</h3>
  <p class="para">
   <ul class="simplelist">
    <li><span class="classname"><a href="class.closure.php" class="classname">Closure</a></span></li>
   </ul>
  </p>
 </div>
</div><?php manual_footer($setup); ?>