1<!doctype html> 2<html lang="en" dir="ltr"> 3<head> 4 <meta charset="utf-8"> 5 6 7 8 9 <title>Upgrade Guide | AMPHP</title> 10 11 <meta name="description" content="Learn how to migrate your existing application from generator-based coroutines to fiber-based coroutines."> 12 <meta name="keywords" content="amp, amphp, non-blocking, concurrency, io, php, future, coroutines, revolt"> 13 14 <link rel="preconnect" href="https://fonts.googleapis.com"> 15 <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> 16 <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;600;700;800&family=Source+Code+Pro&display=swap" rel="stylesheet"> 17 18 <link rel="stylesheet" href="/asset/css/screen.css?v=a07dd8504e6ebf583e1e5d00f434c1e919acaa3b"/> 19 20 <!-- non-critical CSS is lazy-loaded --> 21 <link rel="preload" href="https://cdn.jsdelivr.net/npm/@docsearch/css@3" as="style" type="text/css"> 22 <noscript><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@docsearch/css@3" type="text/css"></noscript> 23 <link rel="preload" href="/asset/css/font-awesome.min.css?v=a07dd8504e6ebf583e1e5d00f434c1e919acaa3b" as="style" type="text/css"> 24 <noscript><link rel="stylesheet" href="/asset/css/font-awesome.min.css?v=a07dd8504e6ebf583e1e5d00f434c1e919acaa3b" type="text/css"></noscript> 25 <link rel="preload" href="/asset/css/code.css?v=a07dd8504e6ebf583e1e5d00f434c1e919acaa3b" as="style" type="text/css"> 26 <noscript><link rel="stylesheet" href="/asset/css/code.css?v=a07dd8504e6ebf583e1e5d00f434c1e919acaa3b" type="text/css"></noscript> 27 28 <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1"> 29 <meta name="google-site-verification" content="lX-Oenz4-gpqzuAF71A-3MQBlDfgr9pIQIfrVniz1As"> 30 31 <meta name="twitter:card" content="summary"> 32 <meta name="twitter:site" content="@asyncphp"> 33 <meta name="twitter:creator" content="@asyncphp"> 34 <meta property="og:type" content="website"> 35 <meta property="og:url" content="/upgrade"> 36 <meta property="og:title" content="Upgrade Guide"> 37 <meta property="og:image" content="https://amphp.org/asset/img/og-image.png"> 38 <meta property="og:description" content="Learn how to migrate your existing application from generator-based coroutines to fiber-based coroutines."> 39 <meta property="og:locale" content="en_US"> 40 41 <link rel="shortcut icon" type="image/x-icon" href="/favicon.ico"> 42 43 <meta name="apple-mobile-web-app-title" content="AMPHP"> 44 <meta name="application-name" content="AMPHP"> 45 <meta name="theme-color" content="#1376dd"> 46 47
47<script> 48 function loadScript(src, onload) { 49 var script = document.createElement("script"); 50 script.type = "application/javascript"; 51 script.async = true; 52 script.onload = function () { 53 script.onload = null; 54 if (onload) { 55 onload(); 56 } 57 }; 58 59 (document.getElementsByTagName("head")[0]).appendChild(script); 60 script.src = src; 61 } 62 63 function loadCss(src) { 64 var resource = document.createElement('link'); 65 resource.setAttribute('rel', 'stylesheet'); 66 resource.setAttribute('href', src); 67 resource.setAttribute('type', 'text/css'); 68 69 (document.getElementsByTagName("head")[0]).appendChild(resource); 70 } 71 </script>
71 72 73
73<script> 74 loadCss('https://cdn.jsdelivr.net/npm/@docsearch/css@3'); 75 loadCss('/asset/css/font-awesome.min.css?v=a07dd8504e6ebf583e1e5d00f434c1e919acaa3b'); 76 loadCss('/asset/css/code.css?v=a07dd8504e6ebf583e1e5d00f434c1e919acaa3b'); 77 78 loadScript('/asset/js/anchor.min.js?v=a07dd8504e6ebf583e1e5d00f434c1e919acaa3b', function () { 79 var anchors = new AnchorJS(); 80 anchors.options.icon = "#"; 81 anchors.options.placement = "left"; 82 anchors.add("h2,h3,h4,h5,h6"); 83 }); 84 85 loadScript('https://cdnjs.cloudflare.com/ajax/libs/highlight.js/8.7/highlight.min.js', function () { 86 hljs.configure({tabReplace: ' ', languages: ['php', 'js']}); 87 hljs.initHighlightingOnLoad(); 88 }); 89 90 loadScript('https://cdn.jsdelivr.net/npm/@docsearch/js@3', function () { 91 docsearch({ 92 appId: 'A5ZG0Y68AG', 93 apiKey: '6b0e299ad51fa720d825ab4bca1bd7c7', 94 indexName: 'amphp_v3', 95 container: '#docsearch', 96 debug: false 97 }); 98 }); 99 </script>
99 100</head> 101<body> 102 103 104 105<input type="checkbox" id="menu" name="menu"> 106<header id="top"> 107 <div class="mobile-only" id="menu-switch"> 108 <label for="menu"><i class="fa fa-lg fa-bars"></i></label> 109 </div> 110 111 <div id="logo-container"> 112 <a class="logo" href="/"> 113 <span class="logo-img-container"> 114 <img srcset="/asset/img/logo_text_60.png 1x, /asset/img/logo_text_120.png 2x" class="logo-img" width="200" height="60" alt="Amp Logo"> 115 </span> 116 </a> 117 </div> 118 119 <div class="search"> 120 <div id="docsearch"></div> 121 </div> 122</header> 123<aside class="navigation"> 124 <div class="navigation-scroll"> 125 <div id="top-menu"> 126 <ul> 127 <li> 128 <span class="menu-section open"> 129 Getting Started 130 </span> 131 132 <ul class="open"> 133 <li> 134 <a class="menu-item" href="/installation"> 135 Installation 136 </a> 137 </li> 138 139 <li> 140 <a class="menu-item" href="/architecture"> 141 Architecture 142 </a> 143 </li> 144 145 <li> 146 <a class="menu-item" href="/upgrade"> 147 Upgrade Guide 148 </a> 149 </li> 150 </ul> 151 </li> 152 153 <li> 154 <span class="menu-section open"> 155 Packages 156 </span> 157 158 <ul class="open"> 159 <li> 160 <a class="menu-item d-flex justify-content-between" href="/amp"> 161 <code>amphp/amp</code> 162 <code class="menu-item-version">3.x</code> 163 </a> 164 </li> 165 166 <li> 167 <a class="menu-item d-flex justify-content-between" href="/byte-stream"> 168 <code>amphp/byte-stream</code> 169 <code class="menu-item-version">2.x</code> 170 </a> 171 </li> 172 173 <li> 174 <span class="menu-item d-flex justify-content-between" title="Undocumented" href="/beanstalk"> 175 <code>amphp/beanstalk</code> 176 </span> 177 </li> 178 179 <li> 180 <a class="menu-item d-flex justify-content-between" href="/cache"> 181 <code>amphp/cache</code> 182 <code class="menu-item-version">2.x</code> 183 </a> 184 </li> 185 186 <li> 187 <a class="menu-item d-flex justify-content-between" href="/cluster"> 188 <code>amphp/cluster</code> 189 <code class="menu-item-version">2.x</code> 190 </a> 191 </li> 192 193 <li> 194 <a class="menu-item d-flex justify-content-between" href="/dns"> 195 <code>amphp/dns</code> 196 <code class="menu-item-version">2.x</code> 197 </a> 198 </li> 199 200 <li> 201 <a class="menu-item d-flex justify-content-between" href="/file"> 202 <code>amphp/file</code> 203 <code class="menu-item-version">3.x</code> 204 </a> 205 </li> 206 207 <li> 208 <a class="menu-item d-flex justify-content-between" href="/http"> 209 <code>amphp/http</code> 210 <code class="menu-item-version">2.x</code> 211 </a> 212 </li> 213 214 <li> 215 <a class="menu-item d-flex justify-content-between" href="/http-client"> 216 <code>
216amphp/http-client</code> 217 <code class="menu-item-version">5.x</code> 218 </a> 219 </li> 220 221 <li> 222 <a class="menu-item d-flex justify-content-between" href="/http-server"> 223 <code>amphp/http-server</code> 224 <code class="menu-item-version">3.x</code> 225 </a> 226 </li> 227 228 <li> 229 <a class="menu-item d-flex justify-content-between" href="/http-server-form-parser"> 230 <code>amphp/http-server-form-parser</code> 231 <code class="menu-item-version">2.x</code> 232 </a> 233 </li> 234 235 <li> 236 <a class="menu-item d-flex justify-content-between" href="/http-server-router"> 237 <code>amphp/http-server-router</code> 238 <code class="menu-item-version">2.x</code> 239 </a> 240 </li> 241 242 <li> 243 <a class="menu-item d-flex justify-content-between" href="/http-server-session"> 244 <code>amphp/http-server-session</code> 245 <code class="menu-item-version">2.x</code> 246 </a> 247 </li> 248 249 <li> 250 <a class="menu-item d-flex justify-content-between" href="/http-server-static-content"> 251 <code>amphp/http-server-static-content</code> 252 <code class="menu-item-version">2.x</code> 253 </a> 254 </li> 255 256 <li> 257 <a class="menu-item d-flex justify-content-between" href="/log"> 258 <code>amphp/log</code> 259 <code class="menu-item-version">2.x</code> 260 </a> 261 </li> 262 263 <li> 264 <a class="menu-item d-flex justify-content-between" href="/mysql"> 265 <code>amphp/mysql</code> 266 <code class="menu-item-version">3.x</code> 267 </a> 268 </li> 269 270 <li> 271 <a class="menu-item d-flex justify-content-between" href="/parallel"> 272 <code>amphp/parallel</code> 273 <code class="menu-item-version">2.x</code> 274 </a> 275 </li> 276 277 <li> 278 <a class="menu-item d-flex justify-content-between" href="/parser"> 279 <code>amphp/parser</code> 280 <code class="menu-item-version">1.x</code> 281 </a> 282 </li> 283 284 <li> 285 <a class="menu-item d-flex justify-content-between" href="/phpunit-util"> 286 <code>amphp/phpunit-util</code> 287 <code class="menu-item-version">3.x</code> 288 </a> 289 </li> 290 291 <li> 292 <a class="menu-item d-flex justify-content-between" href="/pipeline"> 293 <code>amphp/pipeline</code> 294 <code class="menu-item-version">1.x</code> 295 </a> 296 </li> 297 298 <li> 299 <a class="menu-item d-flex justify-content-between" href="/postgres"> 300 <code>amphp/postgres</code> 301 <code class="menu-item-version">2.x</code> 302 </a> 303 </li> 304 305 <li> 306 <a class="menu-item d-flex justify-content-between" href="/process"> 307 <code>amphp/process</code> 308 <code class="menu-item-version">2.x</code> 309 </a> 310 </li> 311 312 <li> 313 <a class="menu-item d-flex justify-content-between" href="/react-adapter"> 314 <code>amphp/react-adapter</code> 315 <code class="menu-item-version">2.x</code> 316 </a> 317 </li> 318 319 <li> 320 <a class="menu-item d-flex justify-content-between" href="/redis"> 321 <code>amphp/redis</code> 322 <code class="menu-item-version">2.x</code> 323 </a> 324 </li> 325 326 <li>
327 <span class="menu-item d-flex justify-content-between" title="Undocumented" href="/rpc"> 328 <code>amphp/rpc</code> 329 </span> 330 </li> 331 332 <li> 333 <a class="menu-item d-flex justify-content-between" href="/serialization"> 334 <code>amphp/serialization</code> 335 <code class="menu-item-version">1.x</code> 336 </a> 337 </li> 338 339 <li> 340 <a class="menu-item d-flex justify-content-between" href="/socket"> 341 <code>amphp/socket</code> 342 <code class="menu-item-version">2.x</code> 343 </a> 344 </li> 345 346 <li> 347 <a class="menu-item d-flex justify-content-between" href="/sync"> 348 <code>amphp/sync</code> 349 <code class="menu-item-version">2.x</code> 350 </a> 351 </li> 352 353 <li> 354 <a class="menu-item d-flex justify-content-between" href="/websocket-client"> 355 <code>amphp/websocket-client</code> 356 <code class="menu-item-version">2.x</code> 357 </a> 358 </li> 359 360 <li> 361 <a class="menu-item d-flex justify-content-between" href="/websocket-server"> 362 <code>amphp/websocket-server</code> 363 <code class="menu-item-version">4.x</code> 364 </a> 365 </li> 366 367 <li> 368 <a class="menu-item d-flex justify-content-between" href="/windows-registry"> 369 <code>amphp/windows-registry</code> 370 <code class="menu-item-version">1.x</code> 371 </a> 372 </li> 373 </ul> 374 </li> 375 376 <li> 377 <span class="menu-section"> 378 Testing & debugging 379 </span> 380 381 <ul> 382 <li> 383 <a class="menu-item" href="/testing"> 384 Writing tests 385 </a> 386 </li> 387 388 <li> 389 <a class="menu-item" href="/debugging"> 390 Debugging tools 391 </a> 392 </li> 393 </ul> 394 </li> 395 396 <li> 397 <span class="menu-section"> 398 Deployment 399 <!-- Performance & optimization --> 400 </span> 401 402 <ul> 403 <li> 404 <a class="menu-item" href="/extensions"> 405 Scaling with extensions 406 </a> 407 </li> 408 409 <li> 410 <a class="menu-item" href="/production"> 411 Production performance 412 </a> 413 </li> 414 </ul> 415 </li> 416 417 <li> 418 <span class="menu-section"> 419 Community 420 </span> 421 422 <ul> 423 <li> 424 <a class="menu-item" href="/sponsors"> 425 Sponsoring 426 </a> 427 </li> 428 429 <li> 430 <a class="menu-item" href="/support"> 431 Support 432 </a> 433 </li> 434 435 <li> 436 <a class="menu-item" href="/faq"> 437 FAQ 438 </a> 439 </li> 440 </ul> 441 </li> 442 </ul> 443 </div> 444 </div> 445 446
446<script> 447 document.querySelectorAll('.menu-section').forEach(element => { 448 element.addEventListener('click', () => { 449 element.classList.toggle('open'); 450 element.nextElementSibling.classList.toggle('open'); 451 }); 452 }); 453 454 document.querySelectorAll('.menu-item').forEach(element => { 455 if (element.href === window.location.href) { 456 element.classList.add('active'); 457 458 element.parentElement.parentElement.classList.add('open'); 459 element.parentElement.parentElement.previousElementSibling.classList.add('open'); 460 } 461 }); 462 </script>
462 463</aside> 464 465<div class="site-wrapper"> 466 467 468 469<div class="site-width"> 470 <div class="content content-with-sidebar"> 471 <div class="content-main"> 472 <div class="article-header"> 473 <div class="article-intro"> 474 <h1>Upgrade Guide</h1> 475 <p>Learn how to migrate your existing application from generator-based coroutines to fiber-based coroutines.</p> 476 477 <div class="content-actions"> 478 479 <a href="https://github.com/amphp/amphp.org/blob/main/upgrade.md"><i class="fa fa-pencil"></i>Suggest edit</a> 480 481 </div> 482 </div> 483 484 485 <div class="article-header-image-container"> 486 <img src="/asset/img/undraw/undraw_upgrade.svg" class="article-header-image"> 487 </div> 488 489 </div> 490 491 <div class="clear-both"></div> 492 493 <div class="article-content"> 494 <p>Weâve brought fibers into PHP 8.1, and itâs time to make use of them. AMPHP has always been focused on synchronous feeling APIs, and fibers allow leveling-up that approach, removing all the boilerplate.</p> 495 496<p>Fibers are independent call stacks that can be cooperatively scheduled by the event loop. While generator-based coroutines need promises at every function boundary, fiber-based coroutines donât have any need like that. 497They also work fine with built-in functions like <code class="language-plaintext highlighter-rouge">array_map</code>.</p> 498 499<blockquote class="note"> 500 <p>You can read the full <a href="https://wiki.php.net/rfc/fibers">Fiber RFC on wiki.php.net</a> if youâre interested in the low-level details.</p> 501</blockquote> 502 503<blockquote class="todo"> 504 <p>Weâre currently in the process of releasing stable versions based on <a href="https://revolt.run">Revolt</a>. 505This guide is a work-in-progress.</p> 506</blockquote> 507 508<h2 id="event-loop">Event Loop</h2> 509 510<p>AMPHP no longer ships its own event loop. Itâs now based on <a href="https://revolt.run">Revolt</a>. <code class="language-plaintext highlighter-rouge">Revolt\EventLoop</code> is quite similar to Ampâs previous <code class="language-plaintext highlighter-rouge">Amp\Loop</code>. A very important difference is using <code class="language-plaintext highlighter-rouge">float $seconds</code> instead of <code class="language-plaintext highlighter-rouge">int $milliseconds</code> for timers though!</p> 511 512<p><a href="https://revolt.run/fibers"><code class="language-plaintext highlighter-rouge">Suspension</code></a> is a new low-level API in Revolt to automatically suspend a fiber and run the event loop if needed. Thereâs mostly no need to call <code class="language-plaintext highlighter-rouge">Amp\Loop::run()</code> or rather the new equivalent <code class="language-plaintext highlighter-rouge">Revolt\EventLoop::run()</code> anymore. The event loop will just automatically run when thereâs an <code class="language-plaintext highlighter-rouge">await()</code> / <code class="language-plaintext highlighter-rouge">suspend()</code> call, which might also be nested deeply somewhere.</p> 513 514<p>You have to replace <code class="language-plaintext highlighter-rouge">Amp\Loop</code> with <code class="language-plaintext highlighter-rouge">Revolt\EventLoop</code>.</p> 515 516<h2 id="coroutines">Coroutines</h2> 517 518<p>Most migration work will be removing the <code class="language-plaintext highlighter-rouge">Amp\call</code> boilerplate and removing all <code class="language-plaintext highlighter-rouge">yield</code> expressions.</p> 519 520<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">function</span> <span class="n">fetchIssues</span><span class="p">(</span><span class="kt">string</span> <span class="nv">$url</span><span class="p">):</span> <span class="kt">Promise</span> 521<span class="p">{</span> 522 <span class="k">return</span> <span class="nf">call</span><span class="p">(</span><span class="k">function</span> <span class="p">()</span> <span class="k">
522use</span> <span class="p">(</span><span class="nv">$url</span><span class="p">)</span> <span class="p">{</span> 523 <span class="nv">$response</span> <span class="o">=</span> <span class="k">yield</span> <span class="nf">fetch</span><span class="p">(</span><span class="nv">$url</span><span class="p">);</span> 524 <span class="nv">$body</span> <span class="o">=</span> <span class="k">yield</span> <span class="nv">$response</span><span class="o">-></span><span class="nf">getBody</span><span class="p">()</span><span class="o">-></span><span class="nf">buffer</span><span class="p">();</span> 525 526 <span class="k">return</span> <span class="nb">json_decode</span><span class="p">(</span><span class="nv">$body</span><span class="p">,</span> <span class="kc">true</span><span class="p">);</span> 527 <span class="p">});</span> 528<span class="p">}</span> 529</code></pre></div></div> 530 531<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">function</span> <span class="n">fetchIssues</span><span class="p">(</span><span class="kt">string</span> <span class="nv">$url</span><span class="p">):</span> <span class="kt">array</span> 532<span class="p">{</span> 533 <span class="nv">$response</span> <span class="o">=</span> <span class="nf">fetch</span><span class="p">(</span><span class="nv">$url</span><span class="p">);</span> 534 <span class="nv">$body</span> <span class="o">=</span> <span class="nv">$response</span><span class="o">-></span><span class="nf">getBody</span><span class="p">()</span><span class="o">-></span><span class="nf">buffer</span><span class="p">();</span> 535 536 <span class="k">return</span> <span class="nb">json_decode</span><span class="p">(</span><span class="nv">$body</span><span class="p">,</span> <span class="kc">true</span><span class="p">);</span> 537<span class="p">}</span> 538</code></pre></div></div> 539 540<h2 id="promises">Promises</h2> 541 542<p><code class="language-plaintext highlighter-rouge">Future</code> is a replacement for the previous <code class="language-plaintext highlighter-rouge">Promise</code>. 543Thereâs no need for callbacks or <code class="language-plaintext highlighter-rouge">yield</code> anymore! 544Its <code class="language-plaintext highlighter-rouge">await()</code> method is based on fibers and replaces generator based coroutines / <code class="language-plaintext highlighter-rouge">Amp\Promise\wait()</code>.</p> 545 546<ul> 547 <li>Renamed <code class="language-plaintext highlighter-rouge">Amp\Deferred</code> to <code class="language-plaintext highlighter-rouge">Amp\DeferredFuture</code>.</li> 548 <li>Removed <code class="language-plaintext highlighter-rouge">Amp\Promise\wait()</code>: Use <code class="language-plaintext highlighter-rouge">Amp\Future::await()</code> instead, which can be called in any (nested) context unlike before.</li> 549 <li>Removed <code class="language-plaintext highlighter-rouge">Amp\call()</code>: Remove the passed closure boilerplate and all <code class="language-plaintext highlighter-rouge">yield</code> keywords, interruption is handled via fibers now instead of generator coroutines.</li> 550 <li>Removed <code class="language-plaintext highlighter-rouge">Amp\asyncCall()</code>: Replace invocations with <code class="language-plaintext highlighter-rouge">Amp\async()</code>, which starts a new fiber instead of using generators.</li> 551 <li>Removed <code class="language-plaintext highlighter-rouge">Amp\coroutine()</code>: Thereâs no direct replacement.</li> 552 <li>Removed <code class="language-plaintext highlighter-rouge">Amp\asyncCoroutine()</code>: Thereâs no direct replacement.</li> 553 <li>Removed <code class="language-plaintext highlighter-rouge">Amp\Promise\timeout()</code>: <code class="language-plaintext highlighter-rouge">Future::await()</code> accepts an optional <code class="language-plaintext highlighter-rouge">Cancellation</code>, which can be used as a replacement.</li> 554 <li>Removed <code class="language-plaintext highlighter-rouge">Amp\Promise\rethrow()</code>: Unhandled errors are now automatically thrown into the event loop, so thereâs no need for that function anymore.</li> 555 <li>Unhandled errors can be ignored using <code class="language-plaintext highlighter-rouge">Future::ignore()</code> if needed, but should usually be handled in some way.</li> 556 <li>Removed <code class="language-plaintext highlighter-rouge">Amp\Promise\wrap()</code>: Use <code class="language-plaintext highlighter-rouge">Future::finally()</code> instead.</li> 557 <li>Renamed <code class="language-plaintext highlighter-rouge">Amp\getCurrentTime()</code> to <code class="language-plaintext highlighter-rouge">Amp\now()</code>
557 returning the time in seconds instead of milliseconds.</li> 558 <li>Changed <code class="language-plaintext highlighter-rouge">Amp\delay()</code> to accept the delay in seconds now instead of milliseconds.</li> 559 <li>Added <code class="language-plaintext highlighter-rouge">Amp\weakClosure()</code> to allow a class to hold a self-referencing Closure without creating a circular reference that prevents automatic garbage collection.</li> 560 <li>Added <code class="language-plaintext highlighter-rouge">Amp\trapSignal()</code> to await one or multiple signals.</li> 561</ul> 562 563<h2 id="promise-combinators">Promise Combinators</h2> 564 565<p>Promise combinators have been renamed:</p> 566 567<ul> 568 <li><code class="language-plaintext highlighter-rouge">Amp\Promise\race()</code> has been renamed to <code class="language-plaintext highlighter-rouge">Amp\Future\awaitFirst()</code></li> 569 <li><code class="language-plaintext highlighter-rouge">Amp\Promise\first()</code> has been renamed to <code class="language-plaintext highlighter-rouge">Amp\Future\awaitAny()</code></li> 570 <li><code class="language-plaintext highlighter-rouge">Amp\Promise\some()</code> has been renamed to <code class="language-plaintext highlighter-rouge">Amp\Future\awaitAnyN()</code></li> 571 <li><code class="language-plaintext highlighter-rouge">Amp\Promise\any()</code> has been renamed to <code class="language-plaintext highlighter-rouge">Amp\Future\awaitAll()</code></li> 572 <li><code class="language-plaintext highlighter-rouge">Amp\Promise\all()</code> has been renamed to <code class="language-plaintext highlighter-rouge">Amp\Future\await()</code></li> 573</ul> 574 575<h2 id="cancellationtoken">CancellationToken</h2> 576 577<ul> 578 <li><code class="language-plaintext highlighter-rouge">CancellationToken</code> has been renamed to <code class="language-plaintext highlighter-rouge">Cancellation</code>.</li> 579 <li><code class="language-plaintext highlighter-rouge">CancellationTokenSource</code> has been renamed to <code class="language-plaintext highlighter-rouge">DeferredCancellation</code>.</li> 580 <li><code class="language-plaintext highlighter-rouge">NullCancellationToken</code> has been renamed to <code class="language-plaintext highlighter-rouge">NullCancellation</code>.</li> 581 <li><code class="language-plaintext highlighter-rouge">TimeoutCancellationToken</code> has been renamed to <code class="language-plaintext highlighter-rouge">TimeoutCancellation</code>.</li> 582 <li><code class="language-plaintext highlighter-rouge">CombinedCancellationToken</code> has been renamed to <code class="language-plaintext highlighter-rouge">CompositeCancellation</code>.</li> 583 <li><code class="language-plaintext highlighter-rouge">SignalCancellation</code> has been added.</li> 584</ul> 585 586<h2 id="iterators">Iterators</h2> 587 588<p>Iterators have been removed from <code class="language-plaintext highlighter-rouge">amphp/amp</code> as normal PHP iterators can be used with fibers now and thereâs no need for a separate API. 589However, thereâs still some need for <em>concurrent</em> iterators, which is covered by the new <a href="https://github.com/amphp/pipeline"><code class="language-plaintext highlighter-rouge">amphp/pipeline</code></a> library now.</p> 590 591<h2 id="closable">Closable</h2> 592 593<p><code class="language-plaintext highlighter-rouge">Amp\Closable</code> has been added as a new basic interface for closable resources such as streams or sockets.</p> 594 595<h2 id="strict-types">Strict Types</h2> 596 597<p>Strict types now declared in all library files. 598This will affect callbacks invoked within this libraryâs code which use scalar types as parameters. 599Functions used with <code class="language-plaintext highlighter-rouge">Amp\async()</code> are the most likely to be affected by this change â these functions will now be invoked within a strict-types context.</p> 600 601<h2 id="other-packages">Other Packages</h2> 602 603<p>Please have a look at the release notes on GitHub for packages other than <code class="language-plaintext highlighter-rouge">amphp/amp</code> when upgrading.</p> 604 605 </div> 606 </div> 607 </div> 608</div> 609 610 <div id="footer" style="background: #fff"> 611 <div class="site-width"> 612 <div class="content footer-columns py-0"> 613 <div class="text-center"> 614 <ul class="footer-networking-list"> 615 <li class="footer-list-item"><a href="https://github.com/amphp/amp"><i 616 class="fa fa-fw fa-github"></i>GitHub</a></li> 617 <li class="footer-list-item"><a href="https://stackoverflow.com/questions/tagged/amphp"><i 618 class="fa fa-fw fa-stack-overflow"></i>Stack Overflow</a></li> 619 <li class="footer-list-item"><a href="https://t.me/amphpchat"><i class="fa fa-fw fa-telegram"></i>Telegram</a> 620 </li> 621 <li class="footer-list-item"><a href="https://twitter.com/asyncphp"><i class="fa fa-fw fa-twitter"></i>Twitter</a></li> 622 </ul> 623 </div> 624 </div> 625 </div> 626 </div> 627</div> 628 629</body> 630</html>
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.