<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:webfeeds="http://webfeeds.org/rss/1.0" version="2.0">
  <channel>
    <atom:link href="http://pubsubhubbub.appspot.com/" rel="hub"/>
    <atom:link href="https://f43.me/planet-php.xml" rel="self" type="application/rss+xml"/>
    <title>Planet PHP</title>
    <description>People blogging about PHP</description>
    <link>http://planet-php.org</link>
    <webfeeds:icon>https://s2.googleusercontent.com/s2/favicons?alt=feed&amp;domain=planet-php.org</webfeeds:icon>
    <generator>f43.me</generator>
    <lastBuildDate>Sun, 19 Apr 2026 17:09:38 +0200</lastBuildDate>
    <item>
      <title><![CDATA[A huge year of growth for python-oracledb - Christopher Jones]]></title>
      <description><![CDATA[<div><div><h2 id="8a62" class="pw-subtitle-paragraph ht gv gw bf b hu hv hw hx hy hz ia ib ic id ie if ig ih ii cq du">It’s been three years since our ground-breaking python-oracledb driver replaced the venerable cx_Oracle driver, and a year since I gave a status update. This post reviews the features and achievements of python-oracledb over the last year.</h2><div></div><figure class="mz na nb nc nd ne mw mx paragraph-image"><div role="button" tabindex="0" class="nf ng fl nh bh ni"><div class="mw mx my"><picture><source srcset="https://miro.medium.com/v2/resize:fit:640/format:webp/1*0PDyRmHba_bwgL26vST1dw.png 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/1*0PDyRmHba_bwgL26vST1dw.png 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/1*0PDyRmHba_bwgL26vST1dw.png 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/1*0PDyRmHba_bwgL26vST1dw.png 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/1*0PDyRmHba_bwgL26vST1dw.png 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/1*0PDyRmHba_bwgL26vST1dw.png 1100w, https://miro.medium.com/v2/resize:fit:1400/format:webp/1*0PDyRmHba_bwgL26vST1dw.png 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" type="image/webp" /><source data-testid="og" srcset="https://miro.medium.com/v2/resize:fit:640/1*0PDyRmHba_bwgL26vST1dw.png 640w, https://miro.medium.com/v2/resize:fit:720/1*0PDyRmHba_bwgL26vST1dw.png 720w, https://miro.medium.com/v2/resize:fit:750/1*0PDyRmHba_bwgL26vST1dw.png 750w, https://miro.medium.com/v2/resize:fit:786/1*0PDyRmHba_bwgL26vST1dw.png 786w, https://miro.medium.com/v2/resize:fit:828/1*0PDyRmHba_bwgL26vST1dw.png 828w, https://miro.medium.com/v2/resize:fit:1100/1*0PDyRmHba_bwgL26vST1dw.png 1100w, https://miro.medium.com/v2/resize:fit:1400/1*0PDyRmHba_bwgL26vST1dw.png 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" /></picture></div></div><figcaption class="nk ff nl mw mx nm nn bf b bg ab du">Major changes in python-oracle releases from March 2023 to April 2025.</figcaption></figure><p id="965c" class="pw-post-body-paragraph no np gw nq b hu nr ns nt hx nu nv nw nx ny nz oa ob oc od oe of og oh oi oj gp bk">Last year I wrote a post <a class="ag ok" href="https://medium.com/@cjones-oracle/a-celebration-of-python-and-oracle-database-eb1425f87101" rel="noopener">A Celebration of Python and Oracle Database</a> which covered the history of the python-oracledb driver in its first two years since it replaced cx_Oracle. It’s time to bring you up to date.</p><h1 id="3c23" class="ol om gw bf on oo op hw oq or os hz ot ou ov ow ox oy oz pa pb pc pd pe pf pg bk">WHAT’S NEW SINCE 2024</h1><p id="f4d4" class="pw-post-body-paragraph no np gw nq b hu ph ns nt hx pi nv nw nx pj nz oa ob pk od oe of pl oh oi oj gp bk">Python use over the last year has grown rapidly, and the additional features of python-oracledb continue to be attractive to Oracle Database developers, particularly in the AI and data analysis fields. In the few months so far since our 3.0 release, <strong class="nq gx">the number of daily python-oracledb downloads has doubled.</strong></p><p id="5c0d" class="pw-post-body-paragraph no np gw nq b hu nr ns nt hx nu nv nw nx ny nz oa ob oc od oe of og oh oi oj gp bk">The major trends for python-oracledb over the year have been support for Oracle Database 23ai and Oracle Cloud features, and improvements to python-oracledb Thin mode (the default mode without Oracle Client libraries) for parity with Thick mode.</p><p id="9d1f" class="pw-post-body-paragraph no np gw nq b hu nr ns nt hx nu nv nw nx ny nz oa ob oc od oe of og oh oi oj gp bk">Highlights are listed below.</p><h2 id="902b" class="pm om gw bf on pn po dy oq pp pq ea ot nx pr ps pt ob pu pv pw of px py pz qa bk">python-oracledb 2.3.0</h2><p id="d4f7" class="pw-post-body-paragraph no np gw nq b hu ph ns nt hx pi nv nw nx pj nz oa ob pk od oe of pl oh oi oj gp bk">Python-oracledb 2.3 was released in July 2024. Oracle Database 23.5 had just introduced a <code class="cx qb qc qd qe b">BINARY</code> format for the <code class="cx qb qc qd qe b">VECTOR</code> data type, so support was added to the driver. Two-Phase Commit and <code class="cx qb qc qd qe b">BFILE</code> data type support landed in Thin mode (to match Thick mode). A new <code class="cx qb qc qd qe b">ssl_version</code> parameter lets TCPS connections choose a TLS version. There was a new <code class="cx qb qc qd qe b">ping_timeout</code> option for connection pooling to improve reliability. Smaller binaries shipped on Linux: they were small already but we changed to use the gcc <code class="cx qb qc qd qe b">-g0</code> compiler option to make them even tinier. An overall review of Oracle Database’s driver defaults occurred and this lead to the defaults for <code class="cx qb qc qd qe b">tcp_connection_timeout</code> and <code class="cx qb qc qd qe b">retry_delay</code> to change, giving consistent user experience and good default behavior across all languages.</p><p id="1310" class="pw-post-body-paragraph no np gw nq b hu nr ns nt hx nu nv nw nx ny nz oa ob oc od oe of og oh oi oj gp bk">See the <a class="ag ok" href="https://medium.com/@veronica.dumitriu/python-oracledb-2-3-has-been-released-2b3f99aec058" rel="noopener">release announcement</a> and <a class="ag ok" href="https://python-oracledb.readthedocs.io/en/latest/release_notes.html#oracledb-2-3-0-july-2024" rel="noopener ugc nofollow" target="_blank">release notes</a>.</p><h2 id="ad67" class="pm om gw bf on pn po dy oq pp pq ea ot nx pr ps pt ob pu pv pw of px py pz qa bk">python-oracledb 2.4.0</h2><p id="d75c" class="pw-post-body-paragraph no np gw nq b hu ph ns nt hx pi nv nw nx pj nz oa ob pk od oe of pl oh oi oj gp bk">Support for Oracle Database 23ai Pipelining landed. I love this feature and blogged about it several times, e.g. <a class="ag ok" href="https://medium.com/oracledevs/pipelined-database-operation-performance-redux-with-python-oracledb-very-impressive-59cf4ba6a1ac" rel="noopener">Pipelined database operation performance redux with python-oracledb: very impressive</a>. The release also had the start of connection management refactoring with a reworked connection string parser. We have to keep up with the Python community so we added binary packages for Python 3.13, and dropped Python 3.7.</p><p id="25b6" class="pw-post-body-paragraph no np gw nq b hu nr ns nt hx nu nv nw nx ny nz oa ob oc od oe of og oh oi oj gp bk">See the <a class="ag ok" href="https://medium.com/@cjones-oracle/python-oracledb-2-4-has-been-released-46041e38046f" rel="noopener">release announcement</a> and <a class="ag ok" href="https://python-oracledb.readthedocs.io/en/latest/release_notes.html#oracledb-2-4-0-august-2024" rel="noopener ugc nofollow" target="_blank">release notes</a>.</p><h2 id="3036" class="pm om gw bf on pn po dy oq pp pq ea ot nx pr ps pt ob pu pv pw of px py pz qa bk">python-oracledb 2.5.0</h2><p id="5c43" class="pw-post-body-paragraph no np gw nq b hu ph ns nt hx pi nv nw nx pj nz oa ob pk od oe of pl oh oi oj gp bk">LDAP support in Thin mode was a highly requested feature: a <code class="cx qb qc qd qe b">register_protocol()</code> function was added so you can easily use your favorite Python LDAP package. There were improvements to Pipelining with the addition of warnings, and access to column metadata for pipelined queries. A database size attribute <code class="cx qb qc qd qe b">max_identifier_length</code> was introduced to make frameworks like SQLAlchemy more efficient (by avoiding the need for them to execute a full query to find the length). Attributes <code class="cx qb qc qd qe b">program</code>, <code class="cx qb qc qd qe b">terminal</code>, <code class="cx qb qc qd qe b">machine</code>, <code class="cx qb qc qd qe b">osuser</code>, <code class="cx qb qc qd qe b">driver_name</code> can be set in Thin mode and queried in Oracle Database V$ tables. Thin mode users can now set <code class="cx qb qc qd qe b">appcontext</code> and <code class="cx qb qc qd qe b">edition</code> during connection (bringing Thin mode in line with Thick mode). Locale aware <code class="cx qb qc qd qe b">config_dir</code> and <code class="cx qb qc qd qe b">lib_dir</code> path handling changes aid some Windows users. Binary packages are now built using a GitHub <a class="ag ok" href="https://github.com/oracle/python-oracledb/blob/main/.github/workflows/build.yaml" rel="noopener ugc nofollow" target="_blank">action</a>, making builds easier, and giving us a way to create development packages for you to test throughout a release cycle.</p><p id="d8ea" class="pw-post-body-paragraph no np gw nq b hu nr ns nt hx nu nv nw nx ny nz oa ob oc od oe of og oh oi oj gp bk">See the <a class="ag ok" href="https://medium.com/@cjones-oracle/python-oracledb-2-5-brings-greater-flexibility-to-oracle-database-apps-1484d4175657" rel="noopener">release announcement</a> and <a class="ag ok" href="https://python-oracledb.readthedocs.io/en/latest/release_notes.html#oracledb-2-5-0-november-2024" rel="noopener ugc nofollow" target="_blank">release notes</a>.</p><h2 id="6fd0" class="pm om gw bf on pn po dy oq pp pq ea ot nx pr ps pt ob pu pv pw of px py pz qa bk">python-oracledb 3.0.0</h2><p id="a730" class="pw-post-body-paragraph no np gw nq b hu ph ns nt hx pi nv nw nx pj nz oa ob pk od oe of pl oh oi oj gp bk">This was a big release with a lot changing around connection management. There were also two marquee features: Data Frames (for Thin and Thick modes), and AQ support in Thin mode. Altogether the major version bump was deserved.</p><p id="6033" class="pw-post-body-paragraph no np gw nq b hu nr ns nt hx nu nv nw nx ny nz oa ob oc od oe of og oh oi oj gp bk">Data frame support has been a “big deal”, allowing faster and easier access to data for users of popular Python analysis libraries. Check out some of my blog posts, starting with <a class="ag ok" href="https://medium.com/@cjones-oracle/going-10x-faster-with-python-oracledb-data-frames-9fe6ea736697" rel="noopener">Going 10x faster with python-oracledb Data Frames</a>.</p><p id="ff65" class="pw-post-body-paragraph no np gw nq b hu nr ns nt hx nu nv nw nx ny nz oa ob oc od oe of og oh oi oj gp bk">Oracle Database’s Advanced Queueing support in Thin mode was a highly requested feature, and Oracle’s AQ team contributed RAW and ADT payload support.</p><p id="793f" class="pw-post-body-paragraph no np gw nq b hu nr ns nt hx nu nv nw nx ny nz oa ob oc od oe of og oh oi oj gp bk">Oracle Database 23.7 introduced a “sparse” <code class="cx qb qc qd qe b">VECTOR</code> data type. Python-oracledb 3.0 added support for it.</p><p>On the connection side, there were new plugins and hooks; support for Configuration Providers to centralize connection management; support for Cloud Native Authentication; named connection pools; improved Thin mode address list load balancing and failover; Transaction Guard support (in Thin mode to match Thick mode).</p><p id="4757" class="pw-post-body-paragraph no np gw nq b hu nr ns nt hx nu nv nw nx ny nz oa ob oc od oe of og oh oi oj gp bk">See the <a class="ag ok" href="https://medium.com/@cjones-oracle/python-oracledb-3-0-fetches-directly-to-data-frames-ecc9e3cb6a67" rel="noopener">release announcement</a> and <a class="ag ok" href="https://python-oracledb.readthedocs.io/en/latest/release_notes.html#oracledb-3-0-0-march-2025" rel="noopener ugc nofollow" target="_blank">release notes</a>.</p><h2 id="09c1" class="pm om gw bf on pn po dy oq pp pq ea ot nx pr ps pt ob pu pv pw of px py pz qa bk">python-oracledb 3.1.0</h2><p id="f4b1" class="pw-post-body-paragraph no np gw nq b hu ph ns nt hx pi nv nw nx pj nz oa ob pk od oe of pl oh oi oj gp bk">More work from Oracle’s AQ team to bring driver mode parity saw support for JSON payloads and for bulk operations added to Thin mode. AQ support was also added for asyncio users. Data frame improvements included support for additional database data types. Scrollable Cursor support in Thin mode brings parity with Thick mode. We dropped support for Python 3.8, which the Python community had already dropped last year.</p><p id="0617" class="pw-post-body-paragraph no np gw nq b hu nr ns nt hx nu nv nw nx ny nz oa ob oc od oe of og oh oi oj gp bk">See the <a class="ag ok" href="https://medium.com/@cjones-oracle/python-oracledb-3-1-has-been-released-with-improved-advanced-queueing-and-data-frame-features-f46aebdd0a93" rel="noopener">release announcement</a> and <a class="ag ok" href="https://python-oracledb.readthedocs.io/en/latest/release_notes.html#oracledb-3-1-0-april-2025" rel="noopener ugc nofollow" target="_blank">release notes</a>.</p><h2 id="c98a" class="pm om gw bf on pn po dy oq pp pq ea ot nx pr ps pt ob pu pv pw of px py pz qa bk">Frameworks, ORMs, SQL Generators, and Libraries</h2><p id="0130" class="pw-post-body-paragraph no np gw nq b hu ph ns nt hx pi nv nw nx pj nz oa ob pk od oe of pl oh oi oj gp bk">Just as critical to the success of python-oracledb has been its use in frameworks, ORMs, SQL generators, and libraries (did I miss any category?) The trend away from cx_Oracle to support python-oracledb continued, and we thank the user community for their efforts. Two big contributions from our driver team also landed: <code class="cx qb qc qd qe b"><a class="ag ok" href="https://medium.com/oracledevs/sqlalchemy-supports-oracle-database-23ai-vectors-2bec0194fb7a" rel="noopener">VECTOR</a></code><a class="ag ok" href="https://medium.com/oracledevs/sqlalchemy-supports-oracle-database-23ai-vectors-2bec0194fb7a" rel="noopener"> support in SQLAlchemy 2.0.41</a>, and <a class="ag ok" href="https://medium.com/@cjones-oracle/using-django-connection-pooling-248e96696105" rel="noopener">connection pooling in Django 5.2</a>.</p><h2 id="7b21" class="pm om gw bf on pn po dy oq pp pq ea ot nx pr ps pt ob pu pv pw of px py pz qa bk">What’s next?</h2><p id="872f" class="pw-post-body-paragraph no np gw nq b hu ph ns nt hx pi nv nw nx pj nz oa ob pk od oe of pl oh oi oj gp bk">It’s only been a few weeks since our 3.1 release but features are already rolling into <a class="ag ok" href="https://github.com/oracle/python-oracledb/tree/main" rel="noopener ugc nofollow" target="_blank">GitHub</a> for the future 3.2 bundle. As of writing, I can see AQ support for Recipient Lists in Thin mode, and support for Instance Principal authentication merged. Data Frame support for <code class="cx qb qc qd qe b">VECTOR</code> is close. And there will be more!</p><p id="b5ad" class="pw-post-body-paragraph no np gw nq b hu nr ns nt hx nu nv nw nx ny nz oa ob oc od oe of og oh oi oj gp bk">Thanks to you all for using python-oracledb and helping make it a great success.</p><h1 id="ed41" class="ol om gw bf on oo op hw oq or os hz ot ou ov ow ox oy oz pa pb pc pd pe pf pg bk">Python-oracledb Resources</h1><p id="202b" class="pw-post-body-paragraph no np gw nq b hu ph ns nt hx pi nv nw nx pj nz oa ob pk od oe of pl oh oi oj gp bk">Python-oracledb is an open source package for the Python Database API specification with many additions to support advanced Oracle Database features. By default, it is a ‘Thin’ driver that is immediately usable without needing any additional install e.g. no Instant Client is required. Python-oracledb is used by frameworks, ORMs, SQL generation libraries, and other projects.</p><ul class=""><li id="5168" class="no np gw nq b hu nr ns nt hx nu nv nw nx ny nz oa ob oc od oe of og oh oi oj qf qg qh bk"><a class="ag ok" href="https://python-oracledb.readthedocs.io/en/latest/user_guide/installation.html" rel="noopener ugc nofollow" target="_blank">Installation instructions</a></li><li id="a8a2" class="no np gw nq b hu qi ns nt hx qj nv nw nx qk nz oa ob ql od oe of qm oh oi oj qf qg qh bk"><a class="ag ok" href="https://python-oracledb.readthedocs.io/en/latest/index.html" rel="noopener ugc nofollow" target="_blank">Documentation</a></li><li id="1bf0" class="no np gw nq b hu qi ns nt hx qj nv nw nx qk nz oa ob ql od oe of qm oh oi oj qf qg qh bk"><a class="ag ok" href="https://github.com/oracle/python-oracledb/discussions" rel="noopener ugc nofollow" target="_blank">Discussions</a></li><li id="e9d7" class="no np gw nq b hu qi ns nt hx qj nv nw nx qk nz oa ob ql od oe of qm oh oi oj qf qg qh bk"><a class="ag ok" href="https://github.com/oracle/python-oracledb" rel="noopener ugc nofollow" target="_blank">Source code on GitHub</a></li><li id="d500" class="no np gw nq b hu qi ns nt hx qj nv nw nx qk nz oa ob ql od oe of qm oh oi oj qf qg qh bk"><a class="ag ok" href="https://pypi.org/project/oracledb/" rel="noopener ugc nofollow" target="_blank">PyPI</a></li></ul></div></div>]]></description>
      <link>https://cjones-oracle.medium.com/a-huge-year-of-growth-for-python-oracledb-a7df39f46d8b?source=rss-adc937c3a9d------2</link>
      <guid>https://cjones-oracle.medium.com/a-huge-year-of-growth-for-python-oracledb-a7df39f46d8b?source=rss-adc937c3a9d------2</guid>
      <pubDate>Mon, 02 Jun 2025 23:09:00 +0200</pubDate>
    </item>
    <item>
      <title><![CDATA[Going 10x faster with python-oracledb Data Frames - Christopher Jones]]></title>
      <description><![CDATA[<div><div><h2 id="3261" class="pw-subtitle-paragraph ht gv gw bf b hu hv hw hx hy hz ia ib ic id ie if ig ih ii cq du">Oracle Database users gain significant performance and memory improvements by using python-oracledb’s new dataframe support. Here are some results.</h2><div></div><figure class="mz na nb nc nd ne mw mx paragraph-image"><div role="button" tabindex="0" class="nf ng fl nh bh ni"><div class="mw mx my"><picture><source srcset="https://miro.medium.com/v2/resize:fit:640/format:webp/0*1_iSbSRZhUkRO_oD 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/0*1_iSbSRZhUkRO_oD 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/0*1_iSbSRZhUkRO_oD 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/0*1_iSbSRZhUkRO_oD 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/0*1_iSbSRZhUkRO_oD 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/0*1_iSbSRZhUkRO_oD 1100w, https://miro.medium.com/v2/resize:fit:1400/format:webp/0*1_iSbSRZhUkRO_oD 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" type="image/webp" /><source data-testid="og" srcset="https://miro.medium.com/v2/resize:fit:640/0*1_iSbSRZhUkRO_oD 640w, https://miro.medium.com/v2/resize:fit:720/0*1_iSbSRZhUkRO_oD 720w, https://miro.medium.com/v2/resize:fit:750/0*1_iSbSRZhUkRO_oD 750w, https://miro.medium.com/v2/resize:fit:786/0*1_iSbSRZhUkRO_oD 786w, https://miro.medium.com/v2/resize:fit:828/0*1_iSbSRZhUkRO_oD 828w, https://miro.medium.com/v2/resize:fit:1100/0*1_iSbSRZhUkRO_oD 1100w, https://miro.medium.com/v2/resize:fit:1400/0*1_iSbSRZhUkRO_oD 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" /></picture></div></div><figcaption class="nk ff nl mw mx nm nn bf b bg ab du">Photo by <a class="ag no" href="https://unsplash.com/@julianhochgesang?utm_source=medium&amp;utm_medium=referral" rel="noopener ugc nofollow" target="_blank">Julian Hochgesang</a> on <a class="ag no" href="https://unsplash.com/?utm_source=medium&amp;utm_medium=referral" rel="noopener ugc nofollow" target="_blank">Unsplash</a></figcaption></figure><p id="c770" class="pw-post-body-paragraph np nq gw nr b hu ns nt nu hx nv nw nx ny nz oa ob oc od oe of og oh oi oj ok gp bk">Python-oracledb, the Python driver for Oracle Database, can efficiently select data for use with data frame libraries such as <a class="ag no" href="https://arrow.apache.org/docs/python/index.html" rel="noopener ugc nofollow" target="_blank">Apache PyArrow</a>, <a class="ag no" href="https://pandas.pydata.org/" rel="noopener ugc nofollow" target="_blank">Pandas</a>, <a class="ag no" href="https://pola.rs/" rel="noopener ugc nofollow" target="_blank">Polars</a>, <a class="ag no" href="https://numpy.org/" rel="noopener ugc nofollow" target="_blank">NumPy</a>, <a class="ag no" href="https://pytorch.org/" rel="noopener ugc nofollow" target="_blank">PyTorch</a>, or to write files in <a class="ag no" href="https://parquet.apache.org/" rel="noopener ugc nofollow" target="_blank">Apache Parquet </a>format. See the documentation <a class="ag no" href="https://python-oracledb.readthedocs.io/en/latest/user_guide/dataframes.html" rel="noopener ugc nofollow" target="_blank">here</a>.</p><p id="5d77" class="pw-post-body-paragraph np nq gw nr b hu ns nt nu hx nv nw nx ny nz oa ob oc od oe of og oh oi oj ok gp bk">The performance improvements are impressive. From a power user <a class="ag no" href="https://github.com/oracle/python-oracledb/issues/375#issuecomment-2920743324" rel="noopener ugc nofollow" target="_blank">here</a>:</p><blockquote class="ol om on"><p id="6d90" class="np nq oo nr b hu ns nt nu hx nv nw nx ny nz oa ob oc od oe of og oh oi oj ok gp bk">Reporting some results now that I was able to test this out in the wild:</p><p id="d55d" class="np nq oo nr b hu ns nt nu hx nv nw nx ny nz oa ob oc od oe of og oh oi oj ok gp bk">Creating (sparse) numpy ndarrays from DB table, between 2x and 3x faster, gain is both extract and being able to work directly in a more efficient format</p><p id="43b8" class="np nq oo nr b hu ns nt nu hx nv nw nx ny nz oa ob oc od oe of og oh oi oj ok gp bk">Creating (large) numpy recarrays from DB table, between 3x and 10x faster. The larger the data, the larger the benefit (and this is with non zero-copy).</p><p id="394b" class="np nq oo nr b hu ns nt nu hx nv nw nx ny nz oa ob oc od oe of og oh oi oj ok gp bk">Creating PQ files from RecordBatch is about 3x faster and a lot more memory friendly</p><p id="517e" class="np nq oo nr b hu ns nt nu hx nv nw nx ny nz oa ob oc od oe of og oh oi oj ok gp bk">In general, this change enabled some serious performance improvements for me.</p></blockquote><p id="e4d2" class="pw-post-body-paragraph np nq gw nr b hu ns nt nu hx nv nw nx ny nz oa ob oc od oe of og oh oi oj ok gp bk">And another user <a class="ag no" href="https://github.com/oracle/python-oracledb/issues/375#issuecomment-2718268613" rel="noopener ugc nofollow" target="_blank">here</a> says:</p><blockquote class="ol om on"><p id="50aa" class="np nq oo nr b hu ns nt nu hx nv nw nx ny nz oa ob oc od oe of og oh oi oj ok gp bk">I’m seeing, on average a 60% speed up in my extract scripts compared with <code class="cx op oq or os b">pd.read_sql</code>, some tables are as much as 78-85% faster.</p></blockquote><p id="a309" class="pw-post-body-paragraph np nq gw nr b hu ns nt nu hx nv nw nx ny nz oa ob oc od oe of og oh oi oj ok gp bk">These are great numbers! Thanks to both these users for sharing their results.</p><p id="da40" class="pw-post-body-paragraph np nq gw nr b hu ns nt nu hx nv nw nx ny nz oa ob oc od oe of og oh oi oj ok gp bk">Our (Oracle’s driver team) work to improve data frames in python-oracledb is continuing. Projects to support the Oracle Database 23ai VECTOR data type, and to make it easier to insert data frames into Oracle Database, are under way.</p><p id="7e70" class="pw-post-body-paragraph np nq gw nr b hu ns nt nu hx nv nw nx ny nz oa ob oc od oe of og oh oi oj ok gp bk">If you’re interested in data frames, also check out my related blog posts <a class="ag no" href="https://medium.com/oracledevs/python-oracledb-3-0-data-frames-a-new-way-to-query-data-4139418bef82" rel="noopener">python-oracledb 3.0 Data Frames — a new way to query data</a> and <a class="ag no" href="https://medium.com/gitconnected/writing-to-parquet-and-delta-lake-files-from-oracle-database-using-python-5f7382bfcdc6" rel="noopener">Writing to Parquet and Delta Lake files from Oracle Database using Python</a>.</p><h1 id="c963" class="ot ou gw bf ov ow ox hw oy oz pa hz pb pc pd pe pf pg ph pi pj pk pl pm pn po bk">Python-oracledb Resources</h1><ul class=""><li id="a625" class="np nq gw nr b hu pp nt nu hx pq nw nx ny pr oa ob oc ps oe of og pt oi oj ok pu pv pw bk"><strong class="nr gx">Installation instructions</strong>: <a class="ag no" href="https://python-oracledb.readthedocs.io/en/latest/user_guide/installation.html" rel="noopener ugc nofollow" target="_blank">python-oracledb.readthedocs.io/en/latest/installation.html</a></li><li id="260d" class="np nq gw nr b hu px nt nu hx py nw nx ny pz oa ob oc qa oe of og qb oi oj ok pu pv pw bk"><strong class="nr gx">Documentation</strong>: <a class="ag no" href="https://python-oracledb.readthedocs.io/en/latest/index.html" rel="noopener ugc nofollow" target="_blank">python-oracledb.readthedocs.io/en/latest/index.html</a></li><li id="1275" class="np nq gw nr b hu px nt nu hx py nw nx ny pz oa ob oc qa oe of og qb oi oj ok pu pv pw bk"><strong class="nr gx">Discussions</strong>: <a class="ag no" href="https://github.com/oracle/python-oracledb/discussions" rel="noopener ugc nofollow" target="_blank">github.com/oracle/python-oracledb/discussions</a></li><li id="c674" class="np nq gw nr b hu px nt nu hx py nw nx ny pz oa ob oc qa oe of og qb oi oj ok pu pv pw bk"><strong class="nr gx">Source Code</strong>: <a class="ag no" href="https://github.com/oracle/python-oracledb" rel="noopener ugc nofollow" target="_blank">github.com/oracle/python-oracledb</a></li></ul></div></div>]]></description>
      <link>https://medium.com/oracledevs/going-10x-faster-with-python-oracledb-data-frames-9fe6ea736697?source=rss-adc937c3a9d------2</link>
      <guid>https://medium.com/oracledevs/going-10x-faster-with-python-oracledb-data-frames-9fe6ea736697?source=rss-adc937c3a9d------2</guid>
      <pubDate>Mon, 02 Jun 2025 05:46:00 +0200</pubDate>
    </item>
    <item>
      <title><![CDATA[ReactPHP Parallel v2(.1) - Cees-Jan Kiewiet]]></title>
      <description><![CDATA[<p><img alt="Cees-Jan" class="img-circle" src="https://blog.wyrihaximus.net/images/photo-cj.jpg" width="50px" height="50px" /><a href="https://plus.google.com/116291745551237181952?rel=author" target="_blank" itemprop="author" itemscope="itemscope" itemtype="http://schema.org/Person">Cees-Jan Kiewiet</a></p><p><time itemprop="datePublished" datetime="2025-06-02T00:00:00+00:00">2 June 2025</time> - <a href="https://github.com/WyriHaximus/blog.wyrihaximus.net/blob/master/source/_posts/2025-06-02-reactphp-parallel-v2-.1-.markdown">Post source at 🐙</a></p><h4>ReactPHP Parallel v2(.1)</h4><p>With fibers in PHP 8.1 and templates types in <a href="https://reactphp.org/promise/"><code>Promise</code></a> v3 the main focus for ReactPHP Parallel v2 is a simpler type safe user facing API. With <a href="https://reactphp.org/promise/"><code>Promise</code></a> v3 and <a href="https://reactphp.org/async/"><code>Async</code></a> v4 providing exactly with we need to make this transformation.</p><p><img src="https://blog.wyrihaximus.net/images/posts/pexels-wolfgang-weiser-467045605-30720851.jpg" alt="Vibrant Cargo Trains at Hamburg Rail Terminal" /></p><blockquote>
<p><a href="https://www.pexels.com/photo/vibrant-cargo-trains-at-hamburg-rail-terminal-30720851/">Photo by Wolfgang Weiser from Pexels</a></p>
</blockquote><h2 id="early-days">Early Days</h2><p>ReactPHP parallel started out as, and still at it’s core is, a <a href="https://www.php.net/manual/en/class.parallel-future.php"><code>Future</code></a> to <a href="https://reactphp.org/promise/"><code>Promise</code></a> converter. (<a href="https://github.com/reactphp-parallel/future-to-promise-converter">That repository</a> has been archived and the package marked abandoned as the event loop for v2 provides this functionality and is the central place for converting futures and channels.)</p><p>That formed the foundation to get results from threads and push all CPU bound operations there. Around the same time I started working on my <a href="https://github.com/wyrihaximusnet/docker-php">ReactPHP optimized Docker images</a>. Running threads required a ZTS (Zend Thread Safe) PHP version. And by building my own images it was easy to get ext-parallel and other extensions in the same images matching my needs, it gives me an easy to use set up.</p><p>Wrapped it up with a infinite pool of threads and a limited pool, depending on your needs. The former will just run anything while the latter is useful to keep CPU and memory usage under control.</p><h2 id="crazy-ideas">Crazy Ideas</h2><p>Beyond the initial foundation I wanted to create a way to make promises look sync by creating an object proxy. This proved possible by doing the following things:</p><ul><li>Run that code in a thread</li>
<li>Create a proxy for any class that returns a promise</li>
<li>Pass the proxy into the code that runs in the thread</li>
<li>Run the original object in the main thread and proxy calls and results back and forth using channels</li>
</ul><p>The thing that blew my mind at the time was, aside from threads in PHP, is that it works. It worked very well for small and simple calls. The more complex things got the slower things got. Even wrote a PRS-11 container proxy to be injected in the thread and automate everything.</p><p>Created a <a href="https://github.com/reactphp-parallel/psr-15-adapter">PSR-15 adapter</a> to use PSR-15 middleware in a ReactPHP HTTP server without blocking the event loop. Unlike the object proxy this ran the blocking code inside a worker thread pool. Also blogged about that a couple of years ago: <a href="http://localhost:8000/2020/09/next-gen-react-http-psr-15-adapter/"><code>Building the next generation react/http PSR-15 adapter</code></a></p><h2 id="fibers">Fibers</h2><p>With PHP 8.1 Fibers turned those ideas upside down. The object proxy lost it’s purpose and has been archived, so are all related packages to it. It also significantly reduced my use for threads to almost 0. Given that green threads (Fibers) are significantly faster than threads this is the way forward for all but CPU-bound use cases.</p><h2 id="personal-usage">Personal Usage</h2><p>My cluster at home however does run some code that runs image conversion and image manipulation (combining a set of images into one bigger image) for <a href="https://www.wyrimaps.net/wow/"><code>WyriMaps</code></a>. This is where threads shine. The main thread runs <a href="https://github.com/jakubkulhan/bunny"><code>Bunny</code></a> getting messages from <a href="https://www.rabbitmq.com/"><code>RabbitMQ</code></a>. It uses worker threads to do the heaving image work. The conversion isn’t super time consuming, it most of time takes less then a second per image to convert. Bigger images take longer but that’s as expected. Stitching a couple hundred images together into one however can take minutes.</p><pre class="php">$this-&gt;logger-&gt;info($logLine . 'Converting');
$png = $this-&gt;threads-&gt;run(static function (string $from, string $data): string {
    $tmpFileName = '/tmp/' . md5($from) . '.' . md5($data) . '.blp.png';
    $img         = imagecreatefromblp($data, $from);
    unset($data);
    imagepng($img, $tmpFileName, 0, PNG_NO_FILTER);
    imagedestroy($img);
    $contents = file_get_contents($tmpFileName);
    unlink($tmpFileName);
    return $contents;
}, [
    $from,
    await($sourceFile-&gt;getContents()),
]);
$this-&gt;logger-&gt;info($logLine . 'Writing');
await($destination-&gt;putContents($png));
$this-&gt;logger-&gt;info($logLine . 'Converted');
</pre><h2 id="v2">v2</h2><p>Version 2 returns the original focus on running CPU-bound operations in threads. But utilizes fibers to have a sync looking API by doing the following two things:</p><ul><li>Anything that returned a promise in v1 new returns the value the future holds</li>
<li>Anything that returned an observable v1 now returns an <code>iterable</code></li>
</ul><p>This results in a much simpler API: No need to handle promises or <code>await</code> them, plus Observables can now easily used in a <code>foreach</code> without using <a href="https://github.com/WyriHaximus/reactphp-awaitable-observable">external packages</a>.</p><p>All of this, however, means you need to run everything inside a fiber. So the examples while a simpler API, are wrapping all those calls inside a fiber, making gain improvement look less. But, that should be extracted away by your HTTP Server, Queue Worker, etc etc. (For sure mine do, but more on that later this year.)</p><h2 id="v2.1">v2.1</h2><p>v2 was originally planned to be PHP 8.2 and up, but after a support request before release I lowered it to PHP 8.1 with the plan to release v2.1 soon after to bring it back up to PHP 8.2 which turned into PHP 8.3. Mainly due to QA tooling reasons making it easier to maintain it.</p><h2 id="future">Future</h2><p>There are two features I want to bring to ReactPHP Parallel this year. One is updating the Worker Pool package from v1 to v2. It’s a nice syntactic sugar wrapper around other pools to have dedicated pools/threads to specific types of work. This cleans up the API from:</p><pre class="php">$threads-&gt;run(static function (string $file): string {
    return file_get_contents($file);
}, [__FILE__]);
</pre><p>To:</p><pre class="php">$worker-&gt;perform(new File(__FILE__));
</pre><p>The other is adding support for ReactPHP Streams to the streams package. The goal there is to take a ReactPHP Stream and stream is over a channel to a thread, but also the other way around. This could for example using blocking file parsing in the thread and streaming each bit of data we get into a HTTP response:</p><pre class="php">new HttpServer(function (ServerRequestInterface $request) {
    $stream = $threads-&gt;run(static function (string $file): string {
      foreach ((new Reader($from))-&gt;generateRecords() as $row) {
          yield $row + PHP_EOL;
      }
    });
    return new Response(body: $stream);
});
</pre><p>Building ReactPHP Parallel v1 has allowed me to experiment with some really crazy ideas, for that time, that turned out to be working. It thought me how to think about threads and multi core usage on both a single core VPS and Kubernetes, and how that impacts both. And it all started with a need to try and process as many images as possible (which now runs on Serverless using <a href="https://bref.sh/"><code>Bref</code></a> Ironically):</p><p><img src="https://blog.wyrihaximus.net/images/posts/parallel-queue-backlog-graph.jpeg" alt="Parallel Queue Backlog graph" /></p><hr /><p> <a class="FlattrButton c1" title="ReactPHP Parallel v2(.1)" data-flattr-uid="WyriHaximus" data-flattr-tags="text, opensource" data-flattr-category="text" data-flattr-language="en_GB" data-flattr-button="compact" href="https://blog.wyrihaximus.net/2025/06/reactphp-parallel-v2-/">With fibers in PHP 8.1 and templates types in Promise v3 the main focus for ReactPHP Parallel v2 is a simpler type safe user facing API. With Promise v3 and Async v4 providing exactly with we need to make this transformation. Photo by Wolfgang Weiser from Pexels</a></p>]]></description>
      <link>https://blog.wyrihaximus.net/2025/06/reactphp-parallel-v2-/</link>
      <guid>https://blog.wyrihaximus.net/2025/06/reactphp-parallel-v2-/</guid>
      <pubDate>Mon, 02 Jun 2025 02:00:00 +0200</pubDate>
    </item>
    <item>
      <title><![CDATA[SQLAlchemy supports Oracle Database 23ai VECTORs - Christopher Jones]]></title>
      <description><![CDATA[<div><div><h2 id="dc33" class="pw-subtitle-paragraph jk im in bf b jl jm jn jo jp jq jr js jt ju jv jw jx jy jz cq du">The widely used SQLAlchemy “Python SQL Toolkit and Object Relational Mapper” now supports the Oracle Database 23ai VECTOR data type, enabling your AI applications.</h2><div></div><p id="8337" class="pw-post-body-paragraph om on in oo b jl op oq or jo os ot ou gn ov ow ox gq oy oz pa gt pb pc pd pe ho bk">The new support for vectors in SQLAlchemy is courtesy of a code contribution from <a class="ag ha" href="https://github.com/suraj-ora-2020" rel="noopener ugc nofollow" target="_blank">Suraj Shaw</a>, a member of Oracle Database’s driver development group. A big thanks to <a class="ag ha" href="https://github.com/zzzeek" rel="noopener ugc nofollow" target="_blank">Mike Bayer</a> and <a class="ag ha" href="https://github.com/CaselIT" rel="noopener ugc nofollow" target="_blank">Federico Caselli</a> from the SQLAlchemy team for merging the enhancement into SQLAlchemy 2.0.41.</p><figure class="pi pj pk pl pm pn pf pg paragraph-image"><div role="button" tabindex="0" class="po pp fl pq bh pr"><div class="pf pg ph"><picture><source srcset="https://miro.medium.com/v2/resize:fit:640/format:webp/0*KImpjVv9S4fopL0C 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/0*KImpjVv9S4fopL0C 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/0*KImpjVv9S4fopL0C 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/0*KImpjVv9S4fopL0C 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/0*KImpjVv9S4fopL0C 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/0*KImpjVv9S4fopL0C 1100w, https://miro.medium.com/v2/resize:fit:1400/format:webp/0*KImpjVv9S4fopL0C 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" type="image/webp" /><source data-testid="og" srcset="https://miro.medium.com/v2/resize:fit:640/0*KImpjVv9S4fopL0C 640w, https://miro.medium.com/v2/resize:fit:720/0*KImpjVv9S4fopL0C 720w, https://miro.medium.com/v2/resize:fit:750/0*KImpjVv9S4fopL0C 750w, https://miro.medium.com/v2/resize:fit:786/0*KImpjVv9S4fopL0C 786w, https://miro.medium.com/v2/resize:fit:828/0*KImpjVv9S4fopL0C 828w, https://miro.medium.com/v2/resize:fit:1100/0*KImpjVv9S4fopL0C 1100w, https://miro.medium.com/v2/resize:fit:1400/0*KImpjVv9S4fopL0C 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" /></picture></div></div><figcaption class="pt ff pu pf pg pv pw bf b bg ab du">Photo by <a class="ag ha" href="https://unsplash.com/@claybanks?utm_source=medium&amp;utm_medium=referral" rel="noopener ugc nofollow" target="_blank">Clay Banks</a> on <a class="ag ha" href="https://unsplash.com/?utm_source=medium&amp;utm_medium=referral" rel="noopener ugc nofollow" target="_blank">Unsplash</a></figcaption></figure><h1 id="cd60" class="px py in bf pz qa qb jn gk qc qd jq gm qe qf qg qh qi qj qk ql qm qn qo qp qq bk">Vector data in Oracle Database 23ai</h1><p id="53ee" class="pw-post-body-paragraph om on in oo b jl qr oq or jo qs ot ou gn qt ow ox gq qu oz pa gt qv pc pd pe ho bk">Oracle Database 23ai introduced Oracle AI Vector Search as part of the database at no additional charge. Vectors are commonly used in AI to represent the semantics of unstructured data such as images, documents, video, and audio. With the new database feature set, a VECTOR data type was added, being represented as an homogeneous array of 8-bit unsigned integers, 8-bit signed integers, 32-bit floating point numbers, or 64-bit floating point numbers.</p><p id="e12c" class="pw-post-body-paragraph om on in oo b jl op oq or jo os ot ou gn ov ow ox gq oy oz pa gt pb pc pd pe ho bk">Vector columns in Oracle Database 23ai can be created as type:</p><pre class="pi pj pk pl pm qw qx qy bp qz bb bk">VECTOR(&lt;vectorDimensions&gt;, &lt;vectorDimensionFormat&gt;)</pre><p id="7984" class="pw-post-body-paragraph om on in oo b jl op oq or jo os ot ou gn ov ow ox gq oy oz pa gt pb pc pd pe ho bk">where the attributes are:</p><ul class=""><li id="2f9c" class="om on in oo b jl op oq or jo os ot ou gn ov ow ox gq oy oz pa gt pb pc pd pe rf rg rh bk">vectorDimensions: the number of dimensions for the vector data. For example, a point in 3D space is defined by vector data of 3 dimensions, i.e., the (x,y,z) coordinates. For the BINARY vector format, the number of dimensions should be a multiple of 8.</li><li id="fe97" class="om on in oo b jl ri oq or jo rj ot ou gn rk ow ox gq rl oz pa gt rm pc pd pe rf rg rh bk">vectorDimensionFormat: one of the keywords BINARY, INT8, FLOAT32, or FLOAT64 to define the storage format for each dimension value in the vector. The INT8, FLOAT32, or FLOAT64 formats are supported with Oracle Database 23.4. The BINARY format was introduced in Oracle Database 23.5.</li></ul><p id="3211" class="pw-post-body-paragraph om on in oo b jl op oq or jo os ot ou gn ov ow ox gq oy oz pa gt pb pc pd pe ho bk">Both the number of dimension and format can be “flexible”, allowing vectors in a column to have different shapes.</p><p id="a758" class="pw-post-body-paragraph om on in oo b jl op oq or jo os ot ou gn ov ow ox gq oy oz pa gt pb pc pd pe ho bk">For example, the SQL to create a table T that includes a VECTOR column called EMBEDDING using FLOAT64 storage is:</p><pre class="pi pj pk pl pm qw qx qy bp qz bb bk">CREATE TABLE t (id INTEGER NOT NULL,<br />                name VARCHAR2(20 CHAR),<br />                embedding VECTOR(3,FLOAT64),<br />                PRIMARY KEY (id));</pre><p id="0ea2" class="pw-post-body-paragraph om on in oo b jl op oq or jo os ot ou gn ov ow ox gq oy oz pa gt pb pc pd pe ho bk">Oracle Database 23.7 introduced the ability to store sparse vectors as an efficient way to represent VECTOR data where most dimensions have zero values. These are not yet supported through SQLAlchemy.</p><p id="090c" class="pw-post-body-paragraph om on in oo b jl op oq or jo os ot ou gn ov ow ox gq oy oz pa gt pb pc pd pe ho bk">For more information about vectors in the database, refer to the <a class="ag ha" href="https://docs.oracle.com/en/database/oracle/oracle-database/23/vecse/overview-ai-vector-search.html" rel="noopener ugc nofollow" target="_blank">Oracle AI Vector Search User’s Guide</a>.</p><h1 id="dd25" class="px py in bf pz qa qb jn gk qc qd jq gm qe qf qg qh qi qj qk ql qm qn qo qp qq bk">Requirements</h1><p id="d6c1" class="pw-post-body-paragraph om on in oo b jl qr oq or jo qs ot ou gn qt ow ox gq qu oz pa gt qv pc pd pe ho bk">To use VECTORs, you need Oracle Database 23ai. Information at <a class="ag ha" href="https://www.oracle.com/database/free/" rel="noopener ugc nofollow" target="_blank">oracle.com/database/free</a> will show you how to access a free cloud database or alternatively install one also for free. Vector support is being improved in each database “release update” so use the latest available version.</p><p id="0e1f" class="pw-post-body-paragraph om on in oo b jl op oq or jo os ot ou gn ov ow ox gq oy oz pa gt pb pc pd pe ho bk">Next, you need at least version 2.0.41 of <code class="cx rn ro rp qx b">sqlalchemy</code>. You should also update <code class="cx rn ro rp qx b">oracledb</code>, which itself has been keeping pace with the database's vector improvements:</p><pre class="pi pj pk pl pm qw qx qy bp qz bb bk">python -m pip install sqlalchemy oracledb --upgrade</pre><h1 id="5125" class="px py in bf pz qa qb jn gk qc qd jq gm qe qf qg qh qi qj qk ql qm qn qo qp qq bk">Creating VECTORs in SQLAlchemy</h1><p id="06e1" class="pw-post-body-paragraph om on in oo b jl qr oq or jo qs ot ou gn qt ow ox gq qu oz pa gt qv pc pd pe ho bk">[The full code of example used in this post is available on GitHub <a class="ag ha" href="https://gist.github.com/cjbj/aeb0d52c6f0d225447b24f72c9efef21" rel="noopener ugc nofollow" target="_blank">here</a>].</p><p id="38e5" class="pw-post-body-paragraph om on in oo b jl op oq or jo os ot ou gn ov ow ox gq oy oz pa gt pb pc pd pe ho bk">In SQLAlchemy, the following creates the same table schema as earlier shown in SQL*Plus:</p><pre class="pi pj pk pl pm qw qx qy bp qz bb bk">from sqlalchemy import MetaData, Table, Column, Integer, String<br />from sqlalchemy.dialects.oracle import VECTOR, VectorStorageFormatmetadata = MetaData()t = Table(<br />    "t",<br />    metadata,<br />    Column("id", Integer, primary_key=True),<br />    Column("name", String(20)),<br />    Column(<br />        "embedding",<br />        VECTOR(dim=3, storage_format=VectorStorageFormat.FLOAT64),<br />    )<br />)</pre><p id="9fb6" class="pw-post-body-paragraph om on in oo b jl op oq or jo os ot ou gn ov ow ox gq oy oz pa gt pb pc pd pe ho bk">Indexes on VECTOR columns can aid performance, see the SQLAlchemy documentation <a class="ag ha" href="https://docs.sqlalchemy.org/en/20/dialects/oracle.html#vector-indexes" rel="noopener ugc nofollow" target="_blank">VECTOR Indexes</a>. An example “<a class="ag ha" href="https://docs.oracle.com/en/database/oracle/oracle-database/23/vecse/neighbor-partition-vector-index.html" rel="noopener ugc nofollow" target="_blank">Inverted File Flat (IVF)</a>” index is:</p><pre class="pi pj pk pl pm qw qx qy bp qz bb bk">from sqlalchemy.dialects.oracle import VectorIndexConfig, VectorIndexType, VectorDistanceTypeIndex(<br />    "ivf_vector_index",<br />    t.c.embedding,<br />    oracle_vector=VectorIndexConfig(<br />        index_type=VectorIndexType.IVF,<br />        distance=VectorDistanceType.EUCLIDEAN,<br />        accuracy=90,<br />        ivf_neighbor_partitions=5,<br />    ),<br />)</pre><h1 id="a306" class="px py in bf pz qa qb jn gk qc qd jq gm qe qf qg qh qi qj qk ql qm qn qo qp qq bk">Inserting VECTORs in SQLAlchemy</h1><p id="4f18" class="pw-post-body-paragraph om on in oo b jl qr oq or jo qs ot ou gn qt ow ox gq qu oz pa gt qv pc pd pe ho bk">VECTOR data can be inserted using Python list or Python <code class="cx rn ro rp qx b">array.array()</code> objects:</p><pre class="pi pj pk pl pm qw qx qy bp qz bb bk">import array<br />from sqlalchemy import insertwith engine.connect() as connection:<br />    connection.execute(<br />        insert(t),<br />        {"id": 1, "name": "chris", "embedding": array.array('d', [2, 3, 5])},<br />    )<br />    connection.execute(<br />        insert(t),<br />        {"id": 2, "name": "king", "embedding": array.array('d', [0, 100, 200])},<br />    )<br />    connection.execute(<br />        insert(t),<br />        {"id": 3, "name": "scott", "embedding": array.array('d', [30, 1, 0])},<br />    )<br />    connection.execute(<br />        insert(t),<br />        {"id": 4, "name": "suraj", "embedding": array.array('d', [4, 5, 6])},<br />    )<br />    connection.commit()</pre><p id="1ddc" class="pw-post-body-paragraph om on in oo b jl op oq or jo os ot ou gn ov ow ox gq oy oz pa gt pb pc pd pe ho bk">In the real world, you might use a Python vectorization library to create vectors from your source data. Or you might use Oracle Database’s <a class="ag ha" href="https://docs.oracle.com/en/database/oracle/oracle-database/23/vecse/generate-vector-embeddings-node.html" rel="noopener ugc nofollow" target="_blank">built-in vectorization</a>.</p><h1 id="0bfb" class="px py in bf pz qa qb jn gk qc qd jq gm qe qf qg qh qi qj qk ql qm qn qo qp qq bk">Searching VECTORs in SQLAlchemy</h1><p id="6508" class="pw-post-body-paragraph om on in oo b jl qr oq or jo qs ot ou gn qt ow ox gq qu oz pa gt qv pc pd pe ho bk">The fun with vectors comes with queries. You can construct these manually, or use new comparison functions:</p><ul class=""><li id="58c0" class="om on in oo b jl op oq or jo os ot ou gn ov ow ox gq oy oz pa gt pb pc pd pe rf rg rh bk"><code class="cx rn ro rp qx b">l2_distance()</code> - the Euclidean distance between vectors</li><li id="5ceb" class="om on in oo b jl ri oq or jo rj ot ou gn rk ow ox gq rl oz pa gt rm pc pd pe rf rg rh bk"><code class="cx rn ro rp qx b">cosine_distance()</code> - the cosine distance between vectors</li><li id="98cf" class="om on in oo b jl ri oq or jo rj ot ou gn rk ow ox gq rl oz pa gt rm pc pd pe rf rg rh bk"><code class="cx rn ro rp qx b">inner_product()</code> - the inner product of two vectors</li></ul><p id="94d1" class="pw-post-body-paragraph om on in oo b jl op oq or jo os ot ou gn ov ow ox gq oy oz pa gt pb pc pd pe ho bk">An example using <a class="ag ha" href="https://docs.oracle.com/en/database/oracle/oracle-database/23/vecse/euclidean-and-squared-euclidean-distances.html" rel="noopener ugc nofollow" target="_blank">euclidean distance matching</a>, and using <a class="ag ha" href="https://docs.oracle.com/en/database/oracle/oracle-database/23/vecse/understand-approximate-similarity-search-using-vector-indexes.html" rel="noopener ugc nofollow" target="_blank">approximate similarity searching</a> for performance is:</p><pre class="pi pj pk pl pm qw qx qy bp qz bb bk">target_vector = [2, 3, 4]res = connection.execute(<br />    t.select().<br />    order_by(t.c.embedding.l2_distance(target_vector)).<br />    fetch(2, oracle_fetch_approximate=True)<br />)print(f"The vector {target_vector} matched these two users:")<br />for r in res:<br />    print(r)</pre><p id="e976" class="pw-post-body-paragraph om on in oo b jl op oq or jo os ot ou gn ov ow ox gq oy oz pa gt pb pc pd pe ho bk">Here, the vector <code class="cx rn ro rp qx b">[2, 3, 4]</code> is matched against vectors stored in the database. The closest two matches are returned. The output is:</p><pre class="pi pj pk pl pm qw qx qy bp qz bb bk">The vector [2, 3, 4] matched these two users:<br />(1, 'chris', [2.0, 3.0, 5.0])<br />(4, 'suraj', [4.0, 5.0, 6.0])</pre><h1 id="9207" class="px py in bf pz qa qb jn gk qc qd jq gm qe qf qg qh qi qj qk ql qm qn qo qp qq bk">Conclusion</h1><p id="bf23" class="pw-post-body-paragraph om on in oo b jl qr oq or jo qs ot ou gn qt ow ox gq qu oz pa gt qv pc pd pe ho bk">Oracle Database 23ai vector functionality opens new possibilities for your applications. SQLAlchemy users can take immediate advantage and work with AI libraries.</p><p id="3652" class="pw-post-body-paragraph om on in oo b jl op oq or jo os ot ou gn ov ow ox gq oy oz pa gt pb pc pd pe ho bk">Take a moment to review the documentation for all the SQLAlchemy and Oracle Database vector functionality. Let us know what great apps you build!</p><h1 id="e2a3" class="px py in bf pz qa qb jn gk qc qd jq gm qe qf qg qh qi qj qk ql qm qn qo qp qq bk">VECTOR Documentation References</h1><ul class=""><li id="4287" class="om on in oo b jl qr oq or jo qs ot ou gn qt ow ox gq qu oz pa gt qv pc pd pe rf rg rh bk">SQLAlchemy VECTOR documentation is <a class="ag ha" href="https://docs.sqlalchemy.org/en/20/dialects/oracle.html#vector-datatype" rel="noopener ugc nofollow" target="_blank">overview</a> and <a class="ag ha" href="https://docs.sqlalchemy.org/en/20/dialects/oracle.html#sqlalchemy.dialects.oracle.VECTOR" rel="noopener ugc nofollow" target="_blank">VECTOR data type</a>.</li><li id="c2e0" class="om on in oo b jl ri oq or jo rj ot ou gn rk ow ox gq rl oz pa gt rm pc pd pe rf rg rh bk">python-oracledb VECTOR documentation is <a class="ag ha" href="https://python-oracledb.readthedocs.io/en/latest/user_guide/vector_data_type.html" rel="noopener ugc nofollow" target="_blank">here</a>.</li><li id="eea6" class="om on in oo b jl ri oq or jo rj ot ou gn rk ow ox gq rl oz pa gt rm pc pd pe rf rg rh bk">A technical brief is available at <a class="ag ha" href="https://download.oracle.com/ocomdocs/global/python-oracledb_Vector_Technical_Brief_Oracle_Database_23ai.pdf" rel="noopener ugc nofollow" target="_blank">Using Oracle Database 23ai Vectors in python-oracledb</a>.</li><li id="61ec" class="om on in oo b jl ri oq or jo rj ot ou gn rk ow ox gq rl oz pa gt rm pc pd pe rf rg rh bk">Oracle Database 23ai VECTOR documentation is <a class="ag ha" href="https://docs.oracle.com/en/database/oracle/oracle-database/23/vecse/overview-ai-vector-search.html" rel="noopener ugc nofollow" target="_blank">here</a>.</li></ul><h1 id="2527" class="px py in bf pz qa qb jn gk qc qd jq gm qe qf qg qh qi qj qk ql qm qn qo qp qq bk">python-oracledb Resources</h1><p id="cf08" class="pw-post-body-paragraph om on in oo b jl qr oq or jo qs ot ou gn qt ow ox gq qu oz pa gt qv pc pd pe ho bk">Python-oracledb is an open source package for the Python Database API specification with many additions to support advanced Oracle Database features. By default, it is a ‘Thin’ driver that is immediately usable without needing any additional install e.g. no Instant Client is required. It is used by many frameworks, ORMs, and libraries such as SQLAlchemy.</p><p id="29ce" class="pw-post-body-paragraph om on in oo b jl op oq or jo os ot ou gn ov ow ox gq oy oz pa gt pb pc pd pe ho bk">Links:</p><ul class=""><li id="8b09" class="om on in oo b jl op oq or jo os ot ou gn ov ow ox gq oy oz pa gt pb pc pd pe rf rg rh bk"><a class="ag ha" href="https://python-oracledb.readthedocs.io/en/latest/user_guide/installation.html" rel="noopener ugc nofollow" target="_blank">Installation instructions</a></li><li id="be25" class="om on in oo b jl ri oq or jo rj ot ou gn rk ow ox gq rl oz pa gt rm pc pd pe rf rg rh bk"><a class="ag ha" href="https://python-oracledb.readthedocs.io/en/latest/index.html" rel="noopener ugc nofollow" target="_blank">Documentation</a></li><li id="bdfa" class="om on in oo b jl ri oq or jo rj ot ou gn rk ow ox gq rl oz pa gt rm pc pd pe rf rg rh bk"><a class="ag ha" href="https://github.com/oracle/python-oracledb/discussions" rel="noopener ugc nofollow" target="_blank">Discussions</a></li><li id="f667" class="om on in oo b jl ri oq or jo rj ot ou gn rk ow ox gq rl oz pa gt rm pc pd pe rf rg rh bk"><a class="ag ha" href="https://github.com/oracle/python-oracledb" rel="noopener ugc nofollow" target="_blank">Source code on GitHub</a></li><li id="0fee" class="om on in oo b jl ri oq or jo rj ot ou gn rk ow ox gq rl oz pa gt rm pc pd pe rf rg rh bk"><a class="ag ha" href="https://pypi.org/project/oracledb/" rel="noopener ugc nofollow" target="_blank">PyPI</a></li></ul><p id="0b2f" class="pw-post-body-paragraph om on in oo b jl op oq or jo os ot ou gn ov ow ox gq oy oz pa gt pb pc pd pe ho bk">You may also like the blog post <a class="ag ha" rel="noopener" href="https://medium.com/oracledevs/python-oracledb-3-0-data-frames-a-new-way-to-query-data-4139418bef82" data-discover="true">python-oracledb 3.0 Data Frames — a new way to query data</a>.</p></div></div>]]></description>
      <link>https://medium.com/oracledevs/sqlalchemy-supports-oracle-database-23ai-vectors-2bec0194fb7a?source=rss-adc937c3a9d------2</link>
      <guid>https://medium.com/oracledevs/sqlalchemy-supports-oracle-database-23ai-vectors-2bec0194fb7a?source=rss-adc937c3a9d------2</guid>
      <pubDate>Fri, 16 May 2025 02:26:00 +0200</pubDate>
    </item>
    <item>
      <title><![CDATA[Additional parameters on a PHP interface method - Rob Allen]]></title>
      <description><![CDATA[<p>On the <a href="http://discord.gg/roave">Roave Discord</a> recently, there was a discussion about not breaking BC in interfaces inspired by <a href="https://phpc.social/@gromnan/114347134096322334">this post by Jérôme Tamarelle</a>:</p><p><img src="https://akrabat.com/wp-content/uploads/2025/04/2025gromnan-post.jpeg" alt="Gromnan post." title="gromnan-post.jpeg" border="0" width="500" height="379" /></p><p>It’s clearly true that if you add a new parameter to a method on an interface, then that’s a BC break as every concrete implementation of the interface needs to change their signature.</p><p>However, Gina commented that you don’t need to use <code>func_get_arg()</code> as concrete implementations can <em>add additional optional arguments</em>.</p><p><strong>WHAT?!!!</strong></p><p>I didn’t know this and it had never occurred to me to try, so I had to go <a href="https://3v4l.org/#live">3v4l.org</a> and check</p><pre>&lt;?php
interface Foo
{
    public function bar(int $a): void;
}
class Baz implements Foo
{
    public function bar(int $a, int $b=2): void
    {
        echo "$a: $b";
    }
}
(new Baz)-&gt;bar(1,3);
</pre><p>Sure enough, this code <a href="https://3v4l.org/judRV">works</a>!</p><p>I don’t have much of a need for this, but it’s useful to know.</p>]]></description>
      <link>https://akrabat.com/additional-parameters-on-a-php-interface-method/</link>
      <guid>https://akrabat.com/additional-parameters-on-a-php-interface-method/</guid>
      <pubDate>Tue, 06 May 2025 12:00:00 +0200</pubDate>
    </item>
    <item>
      <title><![CDATA[Simplifying Python applications by using named connection pools - Christopher Jones]]></title>
      <description><![CDATA[<div><div><h2 id="21a7" class="pw-subtitle-paragraph jk im in bf b jl jm jn jo jp jq jr js jt ju jv jw jx jy jz cq du">Python-oracledb 3.0 allows you to name pools when they are created. You can access them later by that name instead of having to pass around a pool handle. This feature is very helpful when your application spans many code files, or consists of independent libraries.</h2><div></div><figure class="op oq or os ot ou om on paragraph-image"><div role="button" tabindex="0" class="ov ow fl ox bh oy"><div class="om on oo"><picture><source srcset="https://miro.medium.com/v2/resize:fit:640/format:webp/0*hCiEzfOaGScURIKO 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/0*hCiEzfOaGScURIKO 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/0*hCiEzfOaGScURIKO 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/0*hCiEzfOaGScURIKO 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/0*hCiEzfOaGScURIKO 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/0*hCiEzfOaGScURIKO 1100w, https://miro.medium.com/v2/resize:fit:1400/format:webp/0*hCiEzfOaGScURIKO 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" type="image/webp" /><source data-testid="og" srcset="https://miro.medium.com/v2/resize:fit:640/0*hCiEzfOaGScURIKO 640w, https://miro.medium.com/v2/resize:fit:720/0*hCiEzfOaGScURIKO 720w, https://miro.medium.com/v2/resize:fit:750/0*hCiEzfOaGScURIKO 750w, https://miro.medium.com/v2/resize:fit:786/0*hCiEzfOaGScURIKO 786w, https://miro.medium.com/v2/resize:fit:828/0*hCiEzfOaGScURIKO 828w, https://miro.medium.com/v2/resize:fit:1100/0*hCiEzfOaGScURIKO 1100w, https://miro.medium.com/v2/resize:fit:1400/0*hCiEzfOaGScURIKO 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" /></picture></div></div><figcaption class="pa ff pb om on pc pd bf b bg ab du">Photo by <a class="ag ha" href="https://unsplash.com/@tho_gab?utm_source=medium&amp;utm_medium=referral" rel="noopener ugc nofollow" target="_blank">Thomas Gabernig</a> on <a class="ag ha" href="https://unsplash.com/?utm_source=medium&amp;utm_medium=referral" rel="noopener ugc nofollow" target="_blank">Unsplash</a></figcaption></figure><p id="76c8" class="pw-post-body-paragraph pe pf in pg b jl ph pi pj jo pk pl pm gn pn po pp gq pq pr ps gt pt pu pv pw ho bk">Multi-user (and some single-user) database applications should almost always use a driver connection pool. This has performance, scalability, and reliability benefits. Check out my previous posts on this topic are <a class="ag ha" rel="noopener" href="https://medium.com/oracledevs/a-driver-connection-pool-a-drcp-pool-or-an-implicit-connection-pool-454f849cf405">A driver connection pool, a DRCP pool, or an Implicit Connection Pool?</a> and <a class="ag ha" rel="noopener" href="https://medium.com/@cjones-oracle/always-use-connection-pools-and-how-909bc2c65444">Always Use Connection Pools — and How</a>.</p><p id="9a16" class="pw-post-body-paragraph pe pf in pg b jl ph pi pj jo pk pl pm gn pn po pp gq pq pr ps gt pt pu pv pw ho bk">But when your application spans multiple files, it can be tricky to pass the pool handle between your code modules. <strong class="pg io">In </strong><a class="ag ha" rel="noopener" href="https://medium.com/oracledevs/python-oracledb-3-0-fetches-directly-to-data-frames-ecc9e3cb6a67"><strong class="pg io">python-oracledb 3.0</strong></a><strong class="pg io"> we introduced a driver connection pool cache to simplify your life</strong>. You can use the pool cache in both python-oracledb Thin and Thick modes with all the Oracle Database versions that python-oracledb supports. The same cache concept has already proven itself in our <a class="ag ha" href="https://node-oracledb.readthedocs.io/en/latest/user_guide/connection_handling.html#connection-pool-caching" rel="noopener ugc nofollow" target="_blank">node-oracledb driver</a>.</p><p id="af39" class="pw-post-body-paragraph pe pf in pg b jl ph pi pj jo pk pl pm gn pn po pp gq pq pr ps gt pt pu pv pw ho bk">To put pool caching into practice, consider the new code <code class="cx px py pz qa b"><a class="ag ha" href="https://gist.github.com/cjbj/823e147818fd174a25506c791b433c06" rel="noopener ugc nofollow" target="_blank">connection_pool_pc.py</a></code> which is a variant of the sample <code class="cx px py pz qa b"><a class="ag ha" href="https://github.com/oracle/python-oracledb/blob/main/samples/connection_pool.py" rel="noopener ugc nofollow" target="_blank">connection_pool.py</a></code>. (Follow those links to see the full files).</p><p id="f667" class="pw-post-body-paragraph pe pf in pg b jl ph pi pj jo pk pl pm gn pn po pp gq pq pr ps gt pt pu pv pw ho bk">The original <code class="cx px py pz qa b">connection_pool.py</code> code creates a pool and returns its handle to the rest of the application:</p><pre class="op oq or os ot qb qa qc bp qd bb bk">    pool = oracledb.create_pool(<br />        user=sample_env.get_main_user(),<br />        password=sample_env.get_main_password(),<br />        dsn=sample_env.get_connect_string(),<br />        params=sample_env.get_pool_params(),<br />        min=pool_min,<br />        max=pool_max,<br />        increment=pool_inc,<br />        session_callback=init_session,<br />    )return pool</pre><p id="1e9e" class="pw-post-body-paragraph pe pf in pg b jl ph pi pj jo pk pl pm gn pn po pp gq pq pr ps gt pt pu pv pw ho bk">The new code in <code class="cx px py pz qa b">connection_pool_pc.py</code> adds a <code class="cx px py pz qa b">pool_alias=my_pool_alias</code> parameter to <code class="cx px py pz qa b">create_pool()</code>. It doesn’t retain, or use, the pool handle returned by <code class="cx px py pz qa b">create_pool()</code>:</p><pre class="op oq or os ot qb qa qc bp qd bb bk">    my_pool_alias = 'mypool'oracledb.create_pool(<br /><strong class="qa io">pool_alias=my_pool_alias,</strong><br />        user=sample_env.get_main_user(),<br />        password=sample_env.get_main_password(),<br />        dsn=sample_env.get_connect_string(),<br />        params=sample_env.get_pool_params(),<br />        min=pool_min,<br />        max=pool_max,<br />        increment=pool_inc,<br />        session_callback=init_session,<br />    )</pre><p id="eda4" class="pw-post-body-paragraph pe pf in pg b jl ph pi pj jo pk pl pm gn pn po pp gq pq pr ps gt pt pu pv pw ho bk">Every time a connection is needed from the pool, the old code:</p><pre class="op oq or os ot qb qa qc bp qd bb bk">with pool.acquire() as connection:</pre><p id="5679" class="pw-post-body-paragraph pe pf in pg b jl ph pi pj jo pk pl pm gn pn po pp gq pq pr ps gt pt pu pv pw ho bk">is replaced to access the pool directly from the <code class="cx px py pz qa b">oracledb</code> module:</p><pre class="op oq or os ot qb qa qc bp qd bb bk">with oracledb.connect(pool_alias=my_pool_alias) as connection:</pre><p id="60ff" class="pw-post-body-paragraph pe pf in pg b jl ph pi pj jo pk pl pm gn pn po pp gq pq pr ps gt pt pu pv pw ho bk">The full diff between the files is:</p><pre class="op oq or os ot qb qa qc bp qd bb bk">71a72,73<br />&gt; my_pool_alias = 'mypool'<br />&gt; <br />88c90,91<br />&lt;     pool = oracledb.create_pool(<br />---<br />&gt;     oracledb.create_pool(<br />&gt;         pool_alias=my_pool_alias,<br />99d101<br />&lt;     return pool<br />101d102<br />&lt; <br />128c129<br />&lt;     with pool.acquire() as connection:<br />---<br />&gt;     with oracledb.connect(pool_alias=my_pool_alias) as connection:<br />172c173<br />&lt;     with pool.acquire() as connection:<br />---<br />&gt;     with oracledb.connect(pool_alias=my_pool_alias) as connection:<br />190c191<br />&lt;     with pool.acquire() as connection:<br />---<br />&gt;     with oracledb.connect(pool_alias=my_pool_alias) as connection:<br />201c202<br />&lt;     pool = start_pool()<br />---<br />&gt;     start_pool()</pre><p id="c70b" class="pw-post-body-paragraph pe pf in pg b jl ph pi pj jo pk pl pm gn pn po pp gq pq pr ps gt pt pu pv pw ho bk">The files run identically.</p><p id="bd97" class="pw-post-body-paragraph pe pf in pg b jl ph pi pj jo pk pl pm gn pn po pp gq pq pr ps gt pt pu pv pw ho bk">The benefit of pool caching is that modules and libraries that access a pool only need to agree on a name (or names — if you have multiple pools). After importing <code class="cx px py pz qa b">oracledb</code>, each part of the code can access a pool directly off the imported <code class="cx px py pz qa b">oracledb</code> module by using the agreed name.</p><p id="4782" class="pw-post-body-paragraph pe pf in pg b jl ph pi pj jo pk pl pm gn pn po pp gq pq pr ps gt pt pu pv pw ho bk">You can also pass options to <code class="cx px py pz qa b">oracledb.connect()</code> that you might have previously passed to <code class="cx px py pz qa b">pool.acquire()</code>. The documented example is when you are using a heterogeneous pool where each connection could be a different user. In that case you can now get a connection from a pool like:</p><pre class="op oq or os ot qb qa qc bp qd bb bk">connection = oracledb.connect(pool_alias=my_pool_alias, user="toto", password=pw)</pre><p id="3aad" class="pw-post-body-paragraph pe pf in pg b jl ph pi pj jo pk pl pm gn pn po pp gq pq pr ps gt pt pu pv pw ho bk">If you need to explicitly close a pool, or otherwise want to get a handle to it, you can call <code class="cx px py pz qa b">get_pool()</code>:</p><pre class="op oq or os ot qb qa qc bp qd bb bk">pool = oracledb.get_pool(my_pool_alias)<br />pool.close()</pre><p id="7921" class="pw-post-body-paragraph pe pf in pg b jl ph pi pj jo pk pl pm gn pn po pp gq pq pr ps gt pt pu pv pw ho bk">Drop us a line if you like this new feature. It’s simple to use, and lets you get on with creating great Python applications for Oracle Database.</p><h1 id="a731" class="qk qf in bf ql qm qn jn gk qo qp jq gm qq qr qs qt qu qv qw qx qy qz ra rb rc bk">Python-oracledb Resources</h1><p id="1476" class="pw-post-body-paragraph pe pf in pg b jl rd pi pj jo re pl pm gn rf po pp gq rg pr ps gt rh pu pv pw ho bk">Python-oracledb is an open source package for the Python Database API specification with many additions to support advanced Oracle Database features. By default, it is a ‘Thin’ driver that is immediately usable without needing any additional install e.g. no Instant Client is required. It is used by many frameworks, ORMs, and libraries.</p><p id="1cfe" class="pw-post-body-paragraph pe pf in pg b jl ph pi pj jo pk pl pm gn pn po pp gq pq pr ps gt pt pu pv pw ho bk">Links:</p><ul class=""><li id="8129" class="pe pf in pg b jl ph pi pj jo pk pl pm gn pn po pp gq pq pr ps gt pt pu pv pw ri rj rk bk"><a class="ag ha" href="https://python-oracledb.readthedocs.io/en/latest/user_guide/installation.html" rel="noopener ugc nofollow" target="_blank">Installation instructions</a></li><li id="8615" class="pe pf in pg b jl rl pi pj jo rm pl pm gn rn po pp gq ro pr ps gt rp pu pv pw ri rj rk bk"><a class="ag ha" href="https://python-oracledb.readthedocs.io/en/latest/index.html" rel="noopener ugc nofollow" target="_blank">Documentation</a></li><li id="3ba9" class="pe pf in pg b jl rl pi pj jo rm pl pm gn rn po pp gq ro pr ps gt rp pu pv pw ri rj rk bk"><a class="ag ha" href="https://github.com/oracle/python-oracledb/discussions" rel="noopener ugc nofollow" target="_blank">Discussions</a></li><li id="6f2d" class="pe pf in pg b jl rl pi pj jo rm pl pm gn rn po pp gq ro pr ps gt rp pu pv pw ri rj rk bk"><a class="ag ha" href="https://github.com/oracle/python-oracledb" rel="noopener ugc nofollow" target="_blank">Source code on GitHub</a></li><li id="7a0c" class="pe pf in pg b jl rl pi pj jo rm pl pm gn rn po pp gq ro pr ps gt rp pu pv pw ri rj rk bk"><a class="ag ha" href="https://pypi.org/project/oracledb/" rel="noopener ugc nofollow" target="_blank">PyPI</a></li></ul></div></div>]]></description>
      <link>https://medium.com/oracledevs/simplifying-python-applications-by-using-named-connection-pools-3aad8aadb452?source=rss-adc937c3a9d------2</link>
      <guid>https://medium.com/oracledevs/simplifying-python-applications-by-using-named-connection-pools-3aad8aadb452?source=rss-adc937c3a9d------2</guid>
      <pubDate>Wed, 16 Apr 2025 23:31:00 +0200</pubDate>
    </item>
    <item>
      <title><![CDATA[Updated python-oracledb tutorial - Christopher Jones]]></title>
      <description><![CDATA[<div><div><h2 id="4162" class="pw-subtitle-paragraph ht gv gw bf b hu hv hw hx hy hz ia ib ic id ie if ig ih ii cq du">The self-paced python-oracledb tutorial has been refreshed.</h2><div></div><figure class="mz na nb nc nd ne mw mx paragraph-image"><div role="button" tabindex="0" class="nf ng fl nh bh ni"><div class="mw mx my"><picture><source srcset="https://miro.medium.com/v2/resize:fit:640/format:webp/0*CzdWtU-LPf54VLPF 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/0*CzdWtU-LPf54VLPF 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/0*CzdWtU-LPf54VLPF 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/0*CzdWtU-LPf54VLPF 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/0*CzdWtU-LPf54VLPF 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/0*CzdWtU-LPf54VLPF 1100w, https://miro.medium.com/v2/resize:fit:1400/format:webp/0*CzdWtU-LPf54VLPF 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" type="image/webp" /><source data-testid="og" srcset="https://miro.medium.com/v2/resize:fit:640/0*CzdWtU-LPf54VLPF 640w, https://miro.medium.com/v2/resize:fit:720/0*CzdWtU-LPf54VLPF 720w, https://miro.medium.com/v2/resize:fit:750/0*CzdWtU-LPf54VLPF 750w, https://miro.medium.com/v2/resize:fit:786/0*CzdWtU-LPf54VLPF 786w, https://miro.medium.com/v2/resize:fit:828/0*CzdWtU-LPf54VLPF 828w, https://miro.medium.com/v2/resize:fit:1100/0*CzdWtU-LPf54VLPF 1100w, https://miro.medium.com/v2/resize:fit:1400/0*CzdWtU-LPf54VLPF 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" /></picture></div></div><figcaption class="nk ff nl mw mx nm nn bf b bg ab du">Photo by <a class="ag no" href="https://unsplash.com/@markuswinkler?utm_source=medium&amp;utm_medium=referral" rel="noopener ugc nofollow" target="_blank">Markus Winkler</a> on <a class="ag no" href="https://unsplash.com/?utm_source=medium&amp;utm_medium=referral" rel="noopener ugc nofollow" target="_blank">Unsplash</a></figcaption></figure><p id="ad8f" class="pw-post-body-paragraph np nq gw nr b hu ns nt nu hx nv nw nx ny nz oa ob oc od oe of og oh oi oj ok gp bk">Our <a class="ag no" href="https://oracle.github.io/python-oracledb/samples/tutorial/Python-and-Oracle-Database-The-New-Wave-of-Scripting.html" rel="noopener ugc nofollow" target="_blank">Python and Oracle Database: The New Wave of Scripting</a> tutorial has had a refresh. This self-paced tutorial shows you how to use the python-oracledb driver to access Oracle Database. It has exercises and solutions. We have run this at conferences and had positive feedback from people new to the Python world. You can try it out on your own computer.</p><p id="6837" class="pw-post-body-paragraph np nq gw nr b hu ns nt nu hx nv nw nx ny nz oa ob oc od oe of og oh oi oj ok gp bk">Once you have done the tutorial, you may also be interested in the container buildable from <a class="ag no" href="https://github.com/oracle/python-oracledb/tree/main/samples/containers/samples_and_db" rel="noopener ugc nofollow" target="_blank">https://github.com/oracle/python-oracledb/tree/main/samples/containers/samples_and_db</a> that installs the general python-oracledb sample scripts in a container with Oracle Database.</p><p id="1cf2" class="pw-post-body-paragraph np nq gw nr b hu ns nt nu hx nv nw nx ny nz oa ob oc od oe of og oh oi oj ok gp bk">If you’re new to this world, check out my colleague’s post and video <a class="ag no" href="https://medium.com/oracledevs/exploring-python-oracledb-a-simplified-approach-to-oracle-database-connectivity-8b0d58ddec15" rel="noopener">Exploring python-oracledb: A Simplified Approach to Oracle Database Connectivity</a>.</p><h1 id="b14b" class="ol om gw bf on oo op hw oq or os hz ot ou ov ow ox oy oz pa pb pc pd pe pf pg bk">Python-oracledb Resources</h1><p class="pw-post-body-paragraph np nq gw nr b hu ph nt nu hx pi nw nx ny pj oa ob oc pk oe of og pl oi oj ok gp bk">Python-oracledb is an open source package for the Python Database API specification with many additions to support advanced Oracle Database features. By default, it is a ‘Thin’ driver that is immediately usable without needing any additional install e.g. no Instant Client is required. It is used by many frameworks, ORMs, and libraries.</p><p class="pw-post-body-paragraph np nq gw nr b hu ns nt nu hx nv nw nx ny nz oa ob oc od oe of og oh oi oj ok gp bk">Links:</p><ul class=""><li class="np nq gw nr b hu ns nt nu hx nv nw nx ny nz oa ob oc od oe of og oh oi oj ok pm pn po bk"><a class="ag no" href="https://python-oracledb.readthedocs.io/en/latest/user_guide/installation.html" rel="noopener ugc nofollow" target="_blank">Installation instructions</a></li><li class="np nq gw nr b hu pp nt nu hx pq nw nx ny pr oa ob oc ps oe of og pt oi oj ok pm pn po bk"><a class="ag no" href="https://python-oracledb.readthedocs.io/en/latest/index.html" rel="noopener ugc nofollow" target="_blank">Documentation</a></li><li class="np nq gw nr b hu pp nt nu hx pq nw nx ny pr oa ob oc ps oe of og pt oi oj ok pm pn po bk"><a class="ag no" href="https://github.com/oracle/python-oracledb/discussions" rel="noopener ugc nofollow" target="_blank">Discussions</a></li><li class="np nq gw nr b hu pp nt nu hx pq nw nx ny pr oa ob oc ps oe of og pt oi oj ok pm pn po bk"><a class="ag no" href="https://github.com/oracle/python-oracledb" rel="noopener ugc nofollow" target="_blank">Source code on GitHub</a></li><li id="ff70" class="np nq gw nr b hu pp nt nu hx pq nw nx ny pr oa ob oc ps oe of og pt oi oj ok pm pn po bk"><a class="ag no" href="https://pypi.org/project/oracledb/" rel="noopener ugc nofollow" target="_blank">PyPI</a></li></ul></div></div>]]></description>
      <link>https://cjones-oracle.medium.com/updated-python-oracledb-tutorial-7f3a15a1bab7?source=rss-adc937c3a9d------2</link>
      <guid>https://cjones-oracle.medium.com/updated-python-oracledb-tutorial-7f3a15a1bab7?source=rss-adc937c3a9d------2</guid>
      <pubDate>Wed, 16 Apr 2025 02:31:00 +0200</pubDate>
    </item>
    <item>
      <title><![CDATA[Building multi-step login forms that work well with password managers - Evert Pot]]></title>
      <description><![CDATA[<p>Password managers are still the best way to manage credentials, and if you are doing things on the web, you should be using one.</p><p>Increasingly, websites are using multi-step login forms. They might first ask for <em>just</em> an email address and only after present users with a password field.</p><figure><img src="https://evertpot.com/assets/posts/login-forms/google-login.png" class="fill-width" alt="image" /><figcaption>Google Login form</figcaption></figure><figure><img src="https://evertpot.com/assets/posts/login-forms/amazon-login.png" class="fill-width" alt="image" /><figcaption>Amazon Login form</figcaption></figure><p>Unfortunately, this doesn’t always work well with password managers. Password managers are such an integral part of the web, I think it’s important as web developers to make this work as best as possible. It’s also an accessibility issue.</p><h2 id="why-do-websites-use-multi-step-login-forms">Why do websites use multi-step login forms?</h2><p>The short version is that many companies want to centralize their login / password management systems for all their employees. This lets them change passwords in a single place, and also disable accounts after an employee leaves the company. This is called Single Sign-On (SSO) and is often facilitates using the SAML or OpenID Connect protocols.</p><p>When you log in with a web application that supports this, and you enter your email, the first thing the system needs to do is check if a SSO system is in place for your account (or the domainname of your email address), and if so they will redirect out to your sign-on system.</p><p>Only if this is not the case, they will present you with a password field.</p><p>Another reason is that systems increasingly allow users to auhtenticate with means other than a password, and similarly they first need to know your email address / username before they can know what login flow to present you with.</p><h2 id="password-managers">Password managers</h2><p>Password managers such as <a href="https://keepassxc.org/">KeepassXC</a>, <a href="https://bitwarden.com/">Bitwarden</a> and <a href="https://1password.com/">1Password</a>, but also the ‘save password’ feature that’s built into browsers look for HTML forms that are roughly ‘login form shaped’ to do their thing. If something looks like a login form, they will suggest or auto-fill your username and password.</p><p>The problem with multi-step login forms that ask for an email address first, is that they no longer look like plain old login forms, which either means that a user has to do more clicks to complete the login, or in the worst case the password manager can’t detect the fields at all and you end up copy-pasting your password. This is pretty annoying and something I see people often yelling about on the internet.</p><h2 id="so-how-do-you-fix-this">So, how do you fix this?</h2><h3 id="1-make-sure-you-have-the-correct-autocomplete-attribute">1. Make sure you have the correct autocomplete attribute</h3><p>If you have a lone <code class="language-plaintext highlighter-rouge">&lt;input&gt;</code> field for the username, it should have the attribute to signal password managers that this is a username field:</p><div class="language-html highlighter-rouge highlight"><pre>&lt;input type="text" autocomplete="username" name="username" required /&gt;
or:
&lt;input type="email" autocomplete="username" name="username" required /&gt;
</pre></div><h3 id="2-add-a-hidden-username-field-on-the-password-page">2. Add a hidden username field on the password page</h3><p>The <a href="https://www.chromium.org/developers/design-documents/form-styles-that-chromium-understands/">Chrome Wiki</a> recommends that when you collect the email first, and redirect the user after to a password page, to include the username field again (prefilled), and hidden with CSS.</p><div class="language-html highlighter-rouge highlight"><pre>&lt;input
    type="email"
    autocomplete="username"
    name="username"
    required
    value="spam@evertpot.com"
    style="display:none"
/&gt;
&lt;input
    type="password"
    autocomplete="password"
    name="password"
    required
/&gt;
</pre></div><p>This is particularly great if the user has multiple accounts on your system. The pre-filled username lets a password manager detect which account is being used to log in.</p><p>This might also be important for ensuring that password managers offer to save the credentials in the first place.</p><p>Many login systems use SMS codes or TOTP (Authenticator App) codes for additional security. Password managers let you store TOTP codes, but in order for your password manager to detect the field, you also need to annotate this correctly:</p><div class="language-html highlighter-rouge highlight"><pre>&lt;input
    type="text"
    autocomplete="one-time-code"
    name="otp"
    required
    pattern="0-9{6}"
    inputmode="numeric"
/&gt;
</pre></div><p>The key attribute here is ‘autocomplete’. You can even get this auto-filled with SMS codes, if you use a <a href="https://wicg.github.io/sms-one-time-codes/">specially formatted SMS</a>, which looks a bit like this:</p><div class="language-plaintext highlighter-rouge highlight"><pre>Your one-time code is 123123
@mydomain #123123
</pre></div><h3 id="if-you-want-users-to-be-able-to-auto-login-use-html-correctly">If you want users to be able to auto-login use HTML correctly.</h3><p>The <a href="https://developer.1password.com/docs/web/compatible-website-design/">1Password</a> site describes that they simulate a ‘click’ on a login button to trigger the login.</p><p>But if there’s no <code class="language-plaintext highlighter-rouge">&lt;button&gt;</code>, it’s less likely password managers will be able to find it. Using HTML correctly is always a good idea. If you use a component library, check what it generates for buttons and if it’s not <code class="language-plaintext highlighter-rouge">&lt;div&gt;</code>’s all the way down.</p><h2 id="password-manager-developers">Password manager developers:</h2><p>Please also try to follow these recommendations! For better or worse, a lot of applications are going to this multi-step flow. <a href="https://github.com/keepassxreboot/keepassxc-browser">KeepassXC-Browser</a> in particular doesn’t handle these cases well, unless you’re one of of their [blessed sites][<a href="https://github.com/keepassxreboot/keepassxc-browser/blob/b186eb1fd286bdc9515bb59f1e5c7e5ec568b41c/keepassxc-browser/common/sites.js#L3">11</a> (<a href="https://github.com/keepassxreboot/keepassxc-browser/issues/2436">feature request</a>).</p><h2 id="references-and-further-reading">References and further reading:</h2><ul><li><a href="https://wicg.github.io/sms-one-time-codes/">Origin-bound one-time codes delivered via SMS</a></li>
<li><a href="https://developer.1password.com/docs/web/compatible-website-design/">Design your website to work best with 1Password</a></li>
<li><a href="https://www.chromium.org/developers/design-documents/form-styles-that-chromium-understands/">Password Form Styles that Chromium Understands</a></li>
<li><a href="https://www.chromium.org/developers/design-documents/create-amazing-password-forms/">Create Amazing Password Forms (chromium.org)</a></li>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/input/password"><code class="language-plaintext highlighter-rouge">&lt;input type="password"&gt;</code> (MDN)</a></li>
<li><a href="https://github.com/keepassxreboot/keepassxc-browser/issues/2436">KeeppassXC-browser rejected feature request to better support multi-step login forms</a></li>
</ul><h2 id="thoughts">Thoughts?</h2><p>If you have further workarounds to make password managers behave well, you can reply to these posts on Mastodon or Bluesky to automatically appear on this website as a comment:</p>]]></description>
      <link>https://evertpot.com/multi-step-login-forms-for-password-managers/</link>
      <guid>https://evertpot.com/multi-step-login-forms-for-password-managers/</guid>
      <pubDate>Sun, 13 Apr 2025 12:28:00 +0200</pubDate>
    </item>
    <item>
      <title><![CDATA[PHP Core Undergoes Security Audit – Results Now Available - PHP: Hypertext Preprocessor]]></title>
      <description><![CDATA[<div><header class="title"><time datetime="2025-05-08T22:02:15+00:00">08 May 2025</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.3.21. This is a bug fix release.</p><p>All PHP 8.3 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.3.21 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.3.21">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2025-05-08T14:51:28+00:00">08 May 2025</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.4.7. This is a bug fix release.</p><p>All PHP 8.4 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.4.7 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.4.7">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2025-04-10T21:09:01+00:00">10 Apr 2025</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.4.6. This is a bug fix release.</p><p>All PHP 8.4 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.4.6 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.4.6">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2025-04-10T15:56:49+00:00">10 Apr 2025</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.3.20. This is a bug fix release.</p><p>All PHP 8.3 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.3.20 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.3.20">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2025-04-10T11:59:24+00:00">10 Apr 2025</time>
</header><div class="newscontent"><p>A focused security audit of the PHP source code (<a href="https://github.com/php/php-src">php/php-src</a>) was recently completed, commissioned by the <a href="https://www.sovereign.tech/">Sovereign Tech Agency</a>, organized by <a href="https://thephp.foundation/">The PHP Foundation</a> in partnership with <a href="https://ostif.org/">OSTIF</a>, and performed by <a href="https://www.quarkslab.com/">Quarkslab</a>. The audit targeted the most critical parts of the codebase, leading to 27 findings, 17 with security implications, including four CVEs.</p><p>All issues have been addressed by the PHP development team. Users are encouraged to upgrade to the latest PHP versions to benefit from these security improvements.</p><p>Read the full <a href="https://thephp.foundation/assets/files/24-07-1730-REP-V1.4_temp.pdf">audit report</a>. More details in <a href="https://thephp.foundation/blog/2025/04/10/php-core-security-audit-results/">the PHP Foundation blog post</a>.</p><p>If your organization is interested in sponsoring further audits, please contact The PHP Foundation team: <a href="mailto:contact@thephp.foundation">contact@thephp.foundation</a>.</p></div></div><div><header class="title"><time datetime="2025-03-13T16:51:14+00:00">13 Mar 2025</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.28. This is a security release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.28 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.28">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2025-03-13T16:02:34+00:00">13 Mar 2025</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.1.32. This is a security release.</p><p>All PHP 8.1 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.1.32 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.1.32">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2025-03-13T14:47:07+00:00">13 Mar 2025</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.4.5. This is a security release.</p><p>All PHP 8.4 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.4.5 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.4.5">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2025-03-13T13:48:14+00:00">13 Mar 2025</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.3.19. This is a security release.</p><p>All PHP 8.3 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.3.19 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.3.19">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2025-02-13T18:53:19+00:00">13 Feb 2025</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.3.17. This is a bug fix release.</p><p>All PHP 8.3 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.3.17 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.3.17">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2025-02-13T17:59:36+00:00">13 Feb 2025</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.4.4. This is a bug fix release.</p><p>All PHP 8.4 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.4.4 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.4.4">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2025-01-17T01:15:24+00:00">17 Jan 2025</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.4.3. This is a bug fix release.</p><p>All PHP 8.4 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.4.3 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.4.3">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2025-01-16T16:36:10+00:00">16 Jan 2025</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.3.16. This is a bug fix release.</p><p>All PHP 8.3 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.3.16 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.3.16">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-12-19T16:53:11+00:00">19 Dec 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.4.2. This is a bug fix release.</p><p>All PHP 8.4 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.4.2 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.4.2">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-12-19T16:40:56+00:00">19 Dec 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.3.15. This is a bug fix release.</p><p>All PHP 8.3 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.3.15 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.3.15">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-12-19T15:47:10+00:00">19 Dec 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.27. This is a bug fix release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.27 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.27">ChangeLog</a>.</p><p>Please note, this is the last bug-fix release for the 8.2.x series. Security fix support will continue until 31 Dec 2026. For more information, please check our <a href="https://www.php.net/supported-versions">Supported Versions</a> page.</p></div></div><div><header class="title"><time datetime="2024-11-21T06:55:34+00:00">21 Nov 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.4.1. This release marks the latest minor release of the PHP language.</p><p>PHP 8.4 comes with numerous improvements and new features such as:</p><p>For source downloads of PHP 8.4.1 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.4.1">ChangeLog</a>.</p><p>The <a href="https://php.net/manual/en/migration84.php">migration guide</a> is available in the PHP Manual. Please consult it for the detailed list of new features and backward incompatible changes.</p><p>Kudos to all the contributors and supporters!</p></div></div><div><header class="title"><time datetime="2024-11-21T06:23:55+00:00">21 Nov 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.1.31. This is a security release.</p><p>All PHP 8.1 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.1.31 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.1.31">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-11-21T04:17:35+00:00">21 Nov 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.3.14. This is a security release.</p><p>All PHP 8.3 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.3.14 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.3.14">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-11-21T03:50:54+00:00">21 Nov 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.26. This is a security release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.26 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.26">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-11-07T18:53:19+00:00">07 Nov 2024</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the release of PHP 8.4.0, RC4. This is the fourth release candidate, continuing the PHP 8.4 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php84">PHP Wiki</a>.</p><p>For source downloads of PHP 8.4.0, RC4 please visit the <a href="https://downloads.php.net/~calvinb">download page</a>.</p><p>Please carefully test this version and report any issues found in the <a href="https://github.com/php/php-src/issues">bug reporting system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.4.0RC4/NEWS">NEWS</a> file or the <a href="https://github.com/php/php-src/blob/php-8.4.0RC4/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be the production-ready, general availability release, planned for 21 November 2024.</p><p>The signatures for the release can be found in <a href="https://gist.github.com/NattyNarwhal/6a107fe3b862ac3e2cf03b013e151eba">the manifest</a> or on <a href="https://qa.php.net/">the QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></div><div><header class="title"><time datetime="2024-10-24T13:22:16+00:00">24 Oct 2024</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the release of PHP 8.4.0, RC3. This is the third release candidate, continuing the PHP 8.4 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php84">PHP Wiki</a>.</p><p>For source downloads of PHP 8.4.0, RC3 please visit the <a href="https://downloads.php.net/~saki">download page</a>.</p><p>Please carefully test this version and report any issues found in the <a href="https://github.com/php/php-src/issues">bug reporting system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.4.0RC3/NEWS">NEWS</a> file or the <a href="https://github.com/php/php-src/blob/php-8.4.0RC3/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be RC 4, planned for 07 November 2024.</p><p>The signatures for the release can be found in <a href="https://gist.github.com/SakiTakamachi/3648bbdbfeadefb8e40b4ad9592d3b6a">the manifest</a> or on <a href="https://qa.php.net/">the QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></div><div><header class="title"><time datetime="2024-10-24T12:54:49+00:00">24 Oct 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.25. This is a bug fix release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.25 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.25">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-10-24T12:05:52+00:00">24 Oct 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.3.13. This is a bug fix release.</p><p>All PHP 8.3 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.3.13 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.3.13">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-10-10T14:04:23+00:00">10 Oct 2024</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the release of PHP 8.4.0, RC2. This is the second release candidate, continuing the PHP 8.4 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php84">PHP Wiki</a>.</p><p>For source downloads of PHP 8.4.0, RC2 please visit the <a href="https://downloads.php.net/~calvinb">download page</a>.</p><p>Please carefully test this version and report any issues found in the <a href="https://github.com/php/php-src/issues">bug reporting system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.4.0RC2/NEWS">NEWS</a> file or the <a href="https://github.com/php/php-src/blob/php-8.4.0RC2/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be RC 3, planned for 24 October 2024.</p><p>The signatures for the release can be found in <a href="https://gist.github.com/NattyNarwhal/ea2bb82ce1e3fb67f385b2d6e2e085dc">the manifest</a> or on <a href="https://qa.php.net/">the QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></div>]]></description>
      <link>https://www.php.net/index.php#2025-04-10-1</link>
      <guid>https://www.php.net/index.php#2025-04-10-1</guid>
      <pubDate>Thu, 10 Apr 2025 02:00:00 +0200</pubDate>
    </item>
    <item>
      <title><![CDATA[Python-oracledb 3.1 has been released with improved Advanced Queueing and Data Frame features - Christopher Jones]]></title>
      <description><![CDATA[<div><div></div><p id="2925" class="pw-post-body-paragraph mk ml gw mm b mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne nf ng nh gp bk">The python-oracledb 3.1 release is now available on PyPI.</p><figure class="nl nm nn no np nq ni nj paragraph-image"><div role="button" tabindex="0" class="nr ns fl nt bh nu"><div class="ni nj nk"><picture><source srcset="https://miro.medium.com/v2/resize:fit:640/format:webp/0*D9kbvEc8J3_SLl82 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/0*D9kbvEc8J3_SLl82 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/0*D9kbvEc8J3_SLl82 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/0*D9kbvEc8J3_SLl82 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/0*D9kbvEc8J3_SLl82 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/0*D9kbvEc8J3_SLl82 1100w, https://miro.medium.com/v2/resize:fit:1400/format:webp/0*D9kbvEc8J3_SLl82 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" type="image/webp" /><source data-testid="og" srcset="https://miro.medium.com/v2/resize:fit:640/0*D9kbvEc8J3_SLl82 640w, https://miro.medium.com/v2/resize:fit:720/0*D9kbvEc8J3_SLl82 720w, https://miro.medium.com/v2/resize:fit:750/0*D9kbvEc8J3_SLl82 750w, https://miro.medium.com/v2/resize:fit:786/0*D9kbvEc8J3_SLl82 786w, https://miro.medium.com/v2/resize:fit:828/0*D9kbvEc8J3_SLl82 828w, https://miro.medium.com/v2/resize:fit:1100/0*D9kbvEc8J3_SLl82 1100w, https://miro.medium.com/v2/resize:fit:1400/0*D9kbvEc8J3_SLl82 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" /></picture></div></div><figcaption class="nw ff nx ni nj ny nz bf b bg ab du">Photo by <a class="ag oa" href="https://unsplash.com/@johnnyabroad?utm_source=medium&amp;utm_medium=referral" rel="noopener ugc nofollow" target="_blank">Jean-Pierre Brungs</a> on <a class="ag oa" href="https://unsplash.com/?utm_source=medium&amp;utm_medium=referral" rel="noopener ugc nofollow" target="_blank">Unsplash</a></figcaption></figure><p id="6119" class="pw-post-body-paragraph mk ml gw mm b mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne nf ng nh gp bk">This is hot on the heels of last month’s big 3.0 release (see <a class="ag oa" href="https://medium.com/oracledevs/python-oracledb-3-0-fetches-directly-to-data-frames-ecc9e3cb6a67" rel="noopener">New release of python-oracledb 3.0 Fetches Directly to Data Frames, has Thin Mode AQ, supports Centralized Configuration Providers, and more</a>). We had originally intended just to do a 3.0.x bug fix release, but some enhancements were ready to ship, so we decided to share them with you now as a feature release.</p><p id="245b" class="pw-post-body-paragraph mk ml gw mm b mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne nf ng nh gp bk">The enhancements are:</p><ul class=""><li id="bcfe" class="mk ml gw mm b mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne nf ng nh ob oc od bk"><a class="ag oa" href="https://python-oracledb.readthedocs.io/en/latest/user_guide/aq.html" rel="noopener ugc nofollow" target="_blank">Advanced Queueing</a> in Thin mode now supports JSON payloads, and bulk enqueueing and dequeuing. These changes continue the progress towards Thin mode parity with Thick mode. AQ support was also extended to the python-oracledb async API too.</li><li id="a094" class="mk ml gw mm b mn oe mp mq mr of mt mu mv og mx my mz oh nb nc nd oi nf ng nh ob oc od bk">The python-oracledb <a class="ag oa" href="https://python-oracledb.readthedocs.io/en/latest/user_guide/sql_execution.html#fetching-data-frames" rel="noopener ugc nofollow" target="_blank">data frame</a> query functionality was extended with support for CLOB, BLOB, and RAW data types.</li><li id="26a9" class="mk ml gw mm b mn oe mp mq mr of mt mu mv og mx my mz oh nb nc nd oi nf ng nh ob oc od bk">Support for <a class="ag oa" href="https://python-oracledb.readthedocs.io/en/latest/user_guide/sql_execution.html#scrollable-cursors" rel="noopener ugc nofollow" target="_blank">scrollable cursors</a> was added to python-oracledb Thin mode. Scrollable cursors are now useable in both modes.</li><li id="8b17" class="mk ml gw mm b mn oe mp mq mr of mt mu mv og mx my mz oh nb nc nd oi nf ng nh ob oc od bk">The other notable change was that we dropped support for Python 3.8, which the upstream maintainers already ceased supporting last year.</li></ul><p id="00da" class="pw-post-body-paragraph mk ml gw mm b mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne nf ng nh gp bk">There are also plenty of bug fixes. Check the <a class="ag oa" href="https://python-oracledb.readthedocs.io/en/latest/release_notes.html#oracledb-3-1-0-april-2025" rel="noopener ugc nofollow" target="_blank">release notes</a> for all the details.</p><h2 id="bfda" class="oj ok gw bf ol om on dy oo op oq ea or mv os ot ou mz ov ow ox nd oy oz pa pb bk">Installing or Upgrading python-oracledb</h2><p id="4367" class="pw-post-body-paragraph mk ml gw mm b mn pc mp mq mr pd mt mu mv pe mx my mz pf nb nc nd pg nf ng nh gp bk">You can install or upgrade python-oracledb by running:</p><pre class="nl nm nn no np ph pi pj bp pk bb bk">python3 -m pip install oracledb --upgrade</pre><p id="e144" class="pw-post-body-paragraph mk ml gw mm b mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne nf ng nh gp bk">The <code class="cx pq pr ps pi b">pip</code> options <code class="cx pq pr ps pi b">--proxy</code> and <code class="cx pq pr ps pi b">--user</code> may be useful in some environments. See <a class="ag oa" href="https://python-oracledb.readthedocs.io/en/latest/user_guide/installation.html" rel="noopener ugc nofollow" target="_blank">Installing python-oracledb</a> for details.</p><h2 id="6ac8" class="oj ok gw bf ol om on dy oo op oq ea or mv os ot ou mz ov ow ox nd oy oz pa pb bk">Python-oracledb Resources</h2><p class="pw-post-body-paragraph mk ml gw mm b mn pc mp mq mr pd mt mu mv pe mx my mz pf nb nc nd pg nf ng nh gp bk">Python-oracledb is an open source package for the Python Database API specification with many additions to support advanced Oracle Database features. By default, it is a ‘Thin’ driver that is immediately usable without needing any additional install e.g. no Instant Client is required. Python-oracledb is used by frameworks, ORMs, SQL generation libraries, and other projects.</p><ul class=""><li class="mk ml gw mm b mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne nf ng nh ob oc od bk"><strong class="mm gx">Installation instructions</strong>: <a class="ag oa" href="https://python-oracledb.readthedocs.io/en/latest/user_guide/installation.html" rel="noopener ugc nofollow" target="_blank">python-oracledb.readthedocs.io/en/latest/installation.html</a></li><li class="mk ml gw mm b mn oe mp mq mr of mt mu mv og mx my mz oh nb nc nd oi nf ng nh ob oc od bk"><strong class="mm gx">Documentation</strong>: <a class="ag oa" href="https://python-oracledb.readthedocs.io/en/latest/index.html" rel="noopener ugc nofollow" target="_blank">python-oracledb.readthedocs.io/en/latest/index.html</a></li><li class="mk ml gw mm b mn oe mp mq mr of mt mu mv og mx my mz oh nb nc nd oi nf ng nh ob oc od bk"><strong class="mm gx">Discussions</strong>: <a class="ag oa" href="https://github.com/oracle/python-oracledb/discussions" rel="noopener ugc nofollow" target="_blank">github.com/oracle/python-oracledb/discussions</a></li><li class="mk ml gw mm b mn oe mp mq mr of mt mu mv og mx my mz oh nb nc nd oi nf ng nh ob oc od bk"><strong class="mm gx">Source Code</strong>: <a class="ag oa" href="https://github.com/oracle/python-oracledb" rel="noopener ugc nofollow" target="_blank">github.com/oracle/python-oracledb</a></li></ul></div>]]></description>
      <link>https://cjones-oracle.medium.com/python-oracledb-3-1-has-been-released-with-improved-advanced-queueing-and-data-frame-features-f46aebdd0a93?source=rss-adc937c3a9d------2</link>
      <guid>https://cjones-oracle.medium.com/python-oracledb-3-1-has-been-released-with-improved-advanced-queueing-and-data-frame-features-f46aebdd0a93?source=rss-adc937c3a9d------2</guid>
      <pubDate>Fri, 04 Apr 2025 00:52:00 +0200</pubDate>
    </item>
    <item>
      <title><![CDATA[High Availability in PHP OCI8 with Oracle Database Application Continuity - Christopher Jones]]></title>
      <description><![CDATA[<div><div><h2 id="913a" class="pw-subtitle-paragraph jk im in bf b jl jm jn jo jp jq jr js jt ju jv jw jx jy jz cq du">This is a demonstration of how Oracle Database’s Application Continuity feature helps PHP OCI8 applications continue running smoothly during unexpected connection and database outages. Users remain unaware of issues. No complex application error handling logic is needed.</h2><div></div><figure class="op oq or os ot ou om on paragraph-image"><div role="button" tabindex="0" class="ov ow fl ox bh oy"><div class="om on oo"><picture><source srcset="https://miro.medium.com/v2/resize:fit:640/format:webp/0*37AmU1sszeJEFX3P 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/0*37AmU1sszeJEFX3P 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/0*37AmU1sszeJEFX3P 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/0*37AmU1sszeJEFX3P 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/0*37AmU1sszeJEFX3P 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/0*37AmU1sszeJEFX3P 1100w, https://miro.medium.com/v2/resize:fit:1400/format:webp/0*37AmU1sszeJEFX3P 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" type="image/webp" /><source data-testid="og" srcset="https://miro.medium.com/v2/resize:fit:640/0*37AmU1sszeJEFX3P 640w, https://miro.medium.com/v2/resize:fit:720/0*37AmU1sszeJEFX3P 720w, https://miro.medium.com/v2/resize:fit:750/0*37AmU1sszeJEFX3P 750w, https://miro.medium.com/v2/resize:fit:786/0*37AmU1sszeJEFX3P 786w, https://miro.medium.com/v2/resize:fit:828/0*37AmU1sszeJEFX3P 828w, https://miro.medium.com/v2/resize:fit:1100/0*37AmU1sszeJEFX3P 1100w, https://miro.medium.com/v2/resize:fit:1400/0*37AmU1sszeJEFX3P 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" /></picture></div></div><figcaption class="pa ff pb om on pc pd bf b bg ab du">Photo by <a class="ag ha" href="https://unsplash.com/@martinsanchez?utm_source=medium&amp;utm_medium=referral" rel="noopener ugc nofollow" target="_blank">Martin Sanchez</a> on <a class="ag ha" href="https://unsplash.com/?utm_source=medium&amp;utm_medium=referral" rel="noopener ugc nofollow" target="_blank">Unsplash</a></figcaption></figure><h1 id="419f" class="pe pf in bf pg ph pi jn gk pj pk jq gm pl pm pn po pp pq pr ps pt pu pv pw px bk">Introduction</h1><p id="4993" class="pw-post-body-paragraph py pz in qa b jl qb qc qd jo qe qf qg gn qh qi qj gq qk ql qm gt qn qo qp qq ho bk">Oracle Database’s <strong class="qa io">Application Continuity</strong> feature reduces the incidence of application errors by automatically reconnecting and replaying interrupted, in-flight transactions after a database connectivity outage. It restores application state seamlessly. AC masks hardware, software, network, storage errors, and timeouts. Applications continue running and users are unaware of outages. The application’s code doesn’t need unnecessary, complex recovery logic. AC, and its sibling <strong class="qa io">Transparent Application Continuity,</strong> are usable with various configurations of Oracle Database, such as RAC and Oracle Autonomous Database.</p><p id="0fd3" class="pw-post-body-paragraph py pz in qa b jl qr qc qd jo qs qf qg gn qt qi qj gq qu ql qm gt qv qo qp qq ho bk">AC and TAC are supported by many language drivers including PHP OCI8.</p><p id="792d" class="pw-post-body-paragraph py pz in qa b jl qr qc qd jo qs qf qg gn qt qi qj gq qu ql qm gt qv qo qp qq ho bk">Application Continuity is recommended for <a class="ag ha" href="https://en.wikipedia.org/wiki/Online_transaction_processing" rel="noopener ugc nofollow" target="_blank">OLTP</a> applications that use an Oracle Database driver pool (such as the <a class="ag ha" href="https://docs.oracle.com/en/database/oracle/oracle-database/23/lnoci/session-and-connection-pooling.html#GUID-F9662FFB-EAEF-495C-96FC-49C6D1D9625C" rel="noopener ugc nofollow" target="_blank">Oracle Call Interface session pool</a>), or for apps that that provide explicit request boundaries. Transparent Application Continuity (TAC) is a functional mode of Application Continuity that doesn’t need the application to use an Oracle session pool. It transparently tracks, and records, sessions and transactional states.</p><p id="cf9c" class="pw-post-body-paragraph py pz in qa b jl qr qc qd jo qs qf qg gn qt qi qj gq qu ql qm gt qv qo qp qq ho bk">For applications that do use an Oracle Database driver pool, it is your choice whether to use AC or TAC.</p><p id="8292" class="pw-post-body-paragraph py pz in qa b jl qr qc qd jo qs qf qg gn qt qi qj gq qu ql qm gt qv qo qp qq ho bk">To understand all the differences between AC and TAC, and see the best practice information and fine print, check the references at the end of this post.</p><h1 id="96a1" class="pe pf in bf pg ph pi jn gk pj pk jq gm pl pm pn po pp pq pr ps pt pu pv pw px bk">Demo</h1><p id="3f48" class="pw-post-body-paragraph py pz in qa b jl qb qc qd jo qe qf qg gn qh qi qj gq qk ql qm gt qn qo qp qq ho bk">Following my earlier blog post <a class="ag ha" href="https://cjones-oracle.medium.com/oracle-application-continuity-for-continuous-availability-633aa570f374" rel="noopener">Oracle Application Continuity — for continuous availability</a>, I enabled TAC on the “high” service of my Oracle Autonomous Database:</p><pre class="op oq or os ot qw qx qy bp qz bb bk">$ sqlplus -l admin@'tcps://adb.melb.oraclecloud.com:1522/abc_cjmtls_high.adb.oraclecloud.com?wallet_location=/Users/cjones/alwaysfree/CJMTLS'SQL&gt; execute dbms_app_cont_admin.enable_tac('abc_cjmtls_high.adb.oraclecloud.com', 'AUTO', 600);</pre><p id="5562" class="pw-post-body-paragraph py pz in qa b jl qr qc qd jo qs qf qg gn qt qi qj gq qu ql qm gt qv qo qp qq ho bk">And checked it was enabled:</p><pre class="op oq or os ot qw qx qy bp qz bb bk">SQL&gt; set pagesize 1000 linesize 150<br />SQL&gt; col name format a60<br />SQL&gt; col failover_type format a15<br />SQL&gt; select name, failover_type from dba_services;NAME                                                         FAILOVER_TYPE<br />------------------------------------------------------------ ---------------<br />ABC_CJMTLS_tp.adb.oraclecloud.com<br />ABC_CJMTLS_high.adb.oraclecloud.com                          AUTO<br />ABC_CJMTLS_medium.adb.oraclecloud.com<br />ABC_CJMTLS_low.adb.oraclecloud.com<br />ABC_CJMTLS_tpurgent.adb.oraclecloud.com<br />ABC_CJMTLS</pre><p id="91d0" class="pw-post-body-paragraph py pz in qa b jl qr qc qd jo qs qf qg gn qt qi qj gq qu ql qm gt qv qo qp qq ho bk">In real life you may prefer to enable it on your ‘TP’ service, per the documentation.</p><h2 id="ea49" class="rf pf in bf pg gj rg dy gk gl rh ea gm gn ri go gp gq rj gr gs gt rk gu gv rl bk">The PHP OCI8 Application</h2><p id="d0be" class="pw-post-body-paragraph py pz in qa b jl qb qc qd jo qe qf qg gn qh qi qj gq qk ql qm gt qn qo qp qq ho bk">The full PHP app I used is available as a GitHub gist <a class="ag ha" href="https://gist.github.com/cjbj/4f70b7b8b77c1b9bb9783b2f24feeef1" rel="noopener ugc nofollow" target="_blank">here</a>.</p><p id="0af6" class="pw-post-body-paragraph py pz in qa b jl qr qc qd jo qs qf qg gn qt qi qj gq qu ql qm gt qv qo qp qq ho bk">It first prints out the connection’s unique session ID and serial number as a handy “kill” statement that a DBA can use to destroy the connection. This interruption to the running application is how the demo simulates an unplanned connectivity outage:</p><pre class="op oq or os ot qw qx qy bp qz bb bk">// Display the SQL that an administrator can run to kill the connection<br />$killsql = "select unique 'alter system kill session '''||sid||','||serial#||''';'||'' from v\$session_connect_info where sid = sys_context('USERENV', 'SID')";<br />$s = oci_parse($c, $killsql);<br />oci_execute($s);<br />$r = oci_fetch_row($s);<br />print("While this script is running, use SQL*Plus to execute:\n   ".$r[0]. "\n");</pre><p id="3bdc" class="pw-post-body-paragraph py pz in qa b jl qr qc qd jo qs qf qg gn qt qi qj gq qu ql qm gt qv qo qp qq ho bk">For example this might print:</p><pre class="op oq or os ot qw qx qy bp qz bb bk">While this script is running, use SQL*Plus to execute:<br />  alter system kill session '16198,41975';</pre><p id="80f1" class="pw-post-body-paragraph py pz in qa b jl qr qc qd jo qs qf qg gn qt qi qj gq qu ql qm gt qv qo qp qq ho bk">The main code loop inserts some data, shows the connection’s current unique session ID and serial number, and then sleeps for a couple of seconds before committing:</p><pre class="op oq or os ot qw qx qy bp qz bb bk">for ($i = 1; $i &lt;= 10; $i++) {$data = "a" . $i;<br />    $s1 = oci_parse($c, "insert into demo (username) values(:un)");<br />    oci_bind_by_name($s1, ":un", $data);<br />    oci_execute($s1, OCI_NO_AUTO_COMMIT);// Show the unique session ID and serial number that identify this connection<br />    $sidsql = "select unique sid || '-' || serial# from v\$session_connect_info where sid = sys_context('USERENV','SID')";<br />    $s2 = oci_parse($c, $sidsql);<br />    oci_execute($s2);<br />    $r = oci_fetch_row($s2);<br />    print("SID-serial#: ". $r[0]. " inserted data ". $i . "\n");sleep(2);oci_commit($c);<br />}</pre><p id="1026" class="pw-post-body-paragraph py pz in qa b jl qr qc qd jo qs qf qg gn qt qi qj gq qu ql qm gt qv qo qp qq ho bk">The table had been created as:</p><pre class="op oq or os ot qw qx qy bp qz bb bk">create table demo (id number generated by default as identity,<br />                   username varchar2(40));</pre><h2 id="ac3a" class="rf pf in bf pg gj rg dy gk gl rh ea gm gn ri go gp gq rj gr gs gt rk gu gv rl bk">With TAC</h2><p id="ff00" class="pw-post-body-paragraph py pz in qa b jl qb qc qd jo qe qf qg gn qh qi qj gq qk ql qm gt qn qo qp qq ho bk">I first edited the app to use the database service that has TAC enabled:</p><pre class="op oq or os ot qw qx qy bp qz bb bk">$service = 'high'; // TAC</pre><p id="81d2" class="pw-post-body-paragraph py pz in qa b jl qr qc qd jo qs qf qg gn qt qi qj gq qu ql qm gt qv qo qp qq ho bk">I then ran the app:</p><pre class="op oq or os ot qw qx qy bp qz bb bk">$ php tac-php.php</pre><p id="ecb9" class="pw-post-body-paragraph py pz in qa b jl qr qc qd jo qs qf qg gn qt qi qj gq qu ql qm gt qv qo qp qq ho bk">This displayed the kill SQL mentioned above, and then it started inserting data:</p><pre class="op oq or os ot qw qx qy bp qz bb bk">Using service: high<br />While this script is running, use SQL*Plus to execute:<br />  alter system kill session '16198,41975';<br />SID-serial#: 16198-41975 inserted data a1<br />SID-serial#: 16198-41975 inserted data a2<br />SID-serial#: 16198-41975 inserted data a3<br />SID-serial#: 16198-41975 inserted data a4<br />SID-serial#: 16198-41975 inserted data a5</pre><p id="5a56" class="pw-post-body-paragraph py pz in qa b jl qr qc qd jo qs qf qg gn qt qi qj gq qu ql qm gt qv qo qp qq ho bk">I let it continue for a few insertions as shown. Then in a separate window running SQL*Plus as the privileged user ADMIN, I executed the displayed SQL statement to kill the PHP connection in an attempt to cause the app to fail:</p><pre class="op oq or os ot qw qx qy bp qz bb bk">SQL&gt; alter system kill session '16198,41975';</pre><p id="1b7b" class="pw-post-body-paragraph py pz in qa b jl qr qc qd jo qs qf qg gn qt qi qj gq qu ql qm gt qv qo qp qq ho bk">But back in the terminal where PHP was running, all I saw was the SID and serial number of the connection change from <code class="cx rm rn ro qx b">16198–41975</code> to <code class="cx rm rn ro qx b">21130–3914</code> while the app continued to run just fine. There was no error thrown. Eventually the app completed correctly by showing the query output to prove all 10 rows had been inserted:</p><pre class="op oq or os ot qw qx qy bp qz bb bk">SID-serial#: 21130-3914 inserted data a6<br />SID-serial#: 21130-3914 inserted data a7<br />SID-serial#: 21130-3914 inserted data a8<br />SID-serial#: 21130-3914 inserted data a9<br />SID-serial#: 21130-3914 inserted data a10<br />The data inserted was:<br />a1<br />a2<br />a3<br />a4<br />a5<br />a6<br />a7<br />a8<br />a9<br />a10</pre><p id="ac34" class="pw-post-body-paragraph py pz in qa b jl qr qc qd jo qs qf qg gn qt qi qj gq qu ql qm gt qv qo qp qq ho bk">This showed TAC successfully and gracefully handled the database “failure”. Oracle TAC had been recording the SQL statements being executed and it was then able to internally reconnect and replay any outstanding database operations after the first connection was killed. The user wasn’t aware there was a problem. The application didn’t need to have any special reconnection and data retry logic.</p><h2 id="1bbe" class="rf pf in bf pg gj rg dy gk gl rh ea gm gn ri go gp gq rj gr gs gt rk gu gv rl bk">Without AC or TAC</h2><p id="f9e1" class="pw-post-body-paragraph py pz in qa b jl qb qc qd jo qe qf qg gn qh qi qj gq qk ql qm gt qn qo qp qq ho bk">To double check the application, I edited the file to use the ‘low’ service that did not have AC or TAC enabled:</p><pre class="op oq or os ot qw qx qy bp qz bb bk">$service = 'low'; // No AC or TAC</pre><p id="1b38" class="pw-post-body-paragraph py pz in qa b jl qr qc qd jo qs qf qg gn qt qi qj gq qu ql qm gt qv qo qp qq ho bk">I re-ran the app:</p><pre class="op oq or os ot qw qx qy bp qz bb bk">$ php tac-php.phpUsing service: low<br />While this script is running, use SQL*Plus to execute:<br />  alter system kill session '11981,61556';<br />SID-serial#: 11981-61556 inserted data a1<br />SID-serial#: 11981-61556 inserted data a2<br />SID-serial#: 11981-61556 inserted data a3<br />SID-serial#: 11981-61556 inserted data a4<br />SID-serial#: 11981-61556 inserted data a5</pre><p id="b4ef" class="pw-post-body-paragraph py pz in qa b jl qr qc qd jo qs qf qg gn qt qi qj gq qu ql qm gt qv qo qp qq ho bk">After a few iterations, I ran the kill statement in SQL*Plus:</p><pre class="op oq or os ot qw qx qy bp qz bb bk">SQL&gt; alter system kill session '11981,61556';</pre><p id="e4ae" class="pw-post-body-paragraph py pz in qa b jl qr qc qd jo qs qf qg gn qt qi qj gq qu ql qm gt qv qo qp qq ho bk">And this time the PHP app immediately terminated with various errors due to the dead connection:</p><pre class="op oq or os ot qw qx qy bp qz bb bk">Warning: oci_commit(): ORA-03113: end-of-file on communication channel<br />Process ID: 64045<br />Session ID: 11981 Serial number: 61556<br />Help: https://docs.oracle.com/error-help/db/ora-03113/ in tac-php.php on line 166</pre><p id="fbd8" class="pw-post-body-paragraph py pz in qa b jl qr qc qd jo qs qf qg gn qt qi qj gq qu ql qm gt qv qo qp qq ho bk">Game over! Unhappy users!</p><h1 id="61b2" class="pe pf in bf pg ph pi jn gk pj pk jq gm pl pm pn po pp pq pr ps pt pu pv pw px bk">Summary</h1><p id="ebfe" class="pw-post-body-paragraph py pz in qa b jl qb qc qd jo qe qf qg gn qh qi qj gq qk ql qm gt qn qo qp qq ho bk">AC and TAC help protect applications from unplanned database node or connection failures. Users are unaware of the issues that they handle. Developers don’t need to code data retry logic to redo incomplete transactions. Since PHP OCI8 uses the Oracle Call Interface session pool, it supports AC and TAC.</p><p id="497a" class="pw-post-body-paragraph py pz in qa b jl qr qc qd jo qs qf qg gn qt qi qj gq qu ql qm gt qv qo qp qq ho bk">The following references should be consulted for more information about Oracle High Availability solutions.</p><h1 id="0950" class="pe pf in bf pg ph pi jn gk pj pk jq gm pl pm pn po pp pq pr ps pt pu pv pw px bk">References</h1><p id="dccb" class="pw-post-body-paragraph py pz in qa b jl qb qc qd jo qe qf qg gn qh qi qj gq qk ql qm gt qn qo qp qq ho bk"><strong class="qa io">Sample code</strong> <a class="ag ha" href="https://gist.github.com/cjbj/4f70b7b8b77c1b9bb9783b2f24feeef1" rel="noopener ugc nofollow" target="_blank">tac-php.php</a></p><p id="2d54" class="pw-post-body-paragraph py pz in qa b jl qr qc qd jo qs qf qg gn qt qi qj gq qu ql qm gt qv qo qp qq ho bk"><strong class="qa io">Use Application Continuity on Autonomous Database Serverless</strong><br /><a class="ag ha" href="https://docs.oracle.com/en/cloud/paas/autonomous-database/serverless/adbsb/application-continuity1.html" rel="noopener ugc nofollow" target="_blank">https://docs.oracle.com/en/cloud/paas/autonomous-database/serverless/adbsb/application-continuity1.html</a></p><p id="d3fa" class="pw-post-body-paragraph py pz in qa b jl qr qc qd jo qs qf qg gn qt qi qj gq qu ql qm gt qv qo qp qq ho bk"><strong class="qa io">High Availability Overview and Best Practices</strong><br /><a class="ag ha" href="https://docs.oracle.com/en/database/oracle/oracle-database/23/haovw/index.html" rel="noopener ugc nofollow" target="_blank">https://docs.oracle.com/en/database/oracle/oracle-database/23/haovw/index.html</a></p><p id="2df5" class="pw-post-body-paragraph py pz in qa b jl qr qc qd jo qs qf qg gn qt qi qj gq qu ql qm gt qv qo qp qq ho bk"><strong class="qa io">Application Checklist for Continuous Service for MAA Solutions</strong><br /><a class="ag ha" href="https://www.oracle.com/a/tech/docs/application-checklist-for-continuous-availability-for-maa.pdf" rel="noopener ugc nofollow" target="_blank">https://www.oracle.com/a/tech/docs/application-checklist-for-continuous-availability-for-maa.pdf</a></p><p id="3bcc" class="pw-post-body-paragraph py pz in qa b jl qr qc qd jo qs qf qg gn qt qi qj gq qu ql qm gt qv qo qp qq ho bk"><strong class="qa io">The Underground PHP and Oracle Manual</strong><br /><a class="ag ha" href="https://www.oracle.com/technetwork/database/database-technologies/php/201212-ug-php-oracle-1884760.pdf" rel="noopener ugc nofollow" target="_blank">https://www.oracle.com/technetwork/database/database-technologies/php/201212-ug-php-oracle-1884760.pdf</a></p><p id="80da" class="pw-post-body-paragraph py pz in qa b jl qr qc qd jo qs qf qg gn qt qi qj gq qu ql qm gt qv qo qp qq ho bk"><strong class="qa io">PHP Oracle OCI8 Manual</strong><br /><a class="ag ha" href="https://www.php.net/manual/en/book.oci8.php" rel="noopener ugc nofollow" target="_blank">https://www.php.net/manual/en/book.oci8.php</a></p><p id="0ca0" class="pw-post-body-paragraph py pz in qa b jl qr qc qd jo qs qf qg gn qt qi qj gq qu ql qm gt qv qo qp qq ho bk"><strong class="qa io">Oracle Call Interface and Application Continuity</strong><br /><a class="ag ha" href="https://docs.oracle.com/en/database/oracle/oracle-database/23/lnoci/high-availability-in-oci.html#GUID-A8DD9422-2F82-42A9-9555-134296416E8F" rel="noopener ugc nofollow" target="_blank">https://docs.oracle.com/en/database/oracle/oracle-database/23/lnoci/high-availability-in-oci.html#GUID-A8DD9422-2F82-42A9-9555-134296416E8F</a></p></div></div>]]></description>
      <link>https://medium.com/oracledevs/high-availability-in-php-oci8-with-oracle-database-application-continuity-75ce97583a21?source=rss-adc937c3a9d------2</link>
      <guid>https://medium.com/oracledevs/high-availability-in-php-oci8-with-oracle-database-application-continuity-75ce97583a21?source=rss-adc937c3a9d------2</guid>
      <pubDate>Fri, 28 Mar 2025 23:32:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[The Go godror driver now supports the Oracle Database 23ai VECTOR data type - Christopher Jones]]></title>
      <description><![CDATA[<div><div><h2 id="e551" class="pw-subtitle-paragraph jk im in bf b jl jm jn jo jp jq jr js jt ju jv jw jx jy jz cq du"><a class="ag ha" href="https://github.com/tgulacsi" rel="noopener ugc nofollow" target="_blank">Tamás Gulácsi’s</a> excellent <a class="ag ha" href="https://github.com/godror/godror" rel="noopener ugc nofollow" target="_blank">godror driver</a> for the Go language now supports the Oracle Database 23ai VECTOR data type, courtesy of a <a class="ag ha" href="https://github.com/godror/godror/pull/364" rel="noopener ugc nofollow" target="_blank">pull request</a> by <a class="ag ha" href="https://github.com/sudarshan12s" rel="noopener ugc nofollow" target="_blank">Sudarshan Soma</a>, a senior member of Oracle Database’s driver development group.</h2><div></div><figure class="op oq or os ot ou om on paragraph-image"><div role="button" tabindex="0" class="ov ow fl ox bh oy"><div class="om on oo"><picture><source srcset="https://miro.medium.com/v2/resize:fit:640/format:webp/0*CzOtX-pU3KRzkXsR 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/0*CzOtX-pU3KRzkXsR 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/0*CzOtX-pU3KRzkXsR 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/0*CzOtX-pU3KRzkXsR 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/0*CzOtX-pU3KRzkXsR 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/0*CzOtX-pU3KRzkXsR 1100w, https://miro.medium.com/v2/resize:fit:1400/format:webp/0*CzOtX-pU3KRzkXsR 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" type="image/webp" /><source data-testid="og" srcset="https://miro.medium.com/v2/resize:fit:640/0*CzOtX-pU3KRzkXsR 640w, https://miro.medium.com/v2/resize:fit:720/0*CzOtX-pU3KRzkXsR 720w, https://miro.medium.com/v2/resize:fit:750/0*CzOtX-pU3KRzkXsR 750w, https://miro.medium.com/v2/resize:fit:786/0*CzOtX-pU3KRzkXsR 786w, https://miro.medium.com/v2/resize:fit:828/0*CzOtX-pU3KRzkXsR 828w, https://miro.medium.com/v2/resize:fit:1100/0*CzOtX-pU3KRzkXsR 1100w, https://miro.medium.com/v2/resize:fit:1400/0*CzOtX-pU3KRzkXsR 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" /></picture></div></div><figcaption class="pa ff pb om on pc pd bf b bg ab du">Photo by <a class="ag ha" href="https://unsplash.com/@bernardhermant?utm_source=medium&amp;utm_medium=referral" rel="noopener ugc nofollow" target="_blank">Bernard Hermant</a> on <a class="ag ha" href="https://unsplash.com/?utm_source=medium&amp;utm_medium=referral" rel="noopener ugc nofollow" target="_blank">Unsplash</a></figcaption></figure><p id="7309" class="pw-post-body-paragraph pe pf in pg b jl ph pi pj jo pk pl pm gn pn po pp gq pq pr ps gt pt pu pv pw ho bk">Oracle Database 23ai introduced a <a class="ag ha" href="https://docs.oracle.com/en/database/oracle/oracle-database/23/vecse/overview-ai-vector-search.html" rel="noopener ugc nofollow" target="_blank">VECTOR data type</a> to aid artificial intelligence and machine learning search operations. Vectors are an homogeneous array of 8-bit signed integers, 8-bit unsigned integers, 32-bit floating-point numbers, or 64-bit floating-point numbers. You can optionally define the number of dimensions for the data. Vectors can be “dense” (the default), or “sparse” when data is mostly zeroes.</p><p id="0a1a" class="pw-post-body-paragraph pe pf in pg b jl ph pi pj jo pk pl pm gn pn po pp gq pq pr ps gt pt pu pv pw ho bk">For example to create a table with two VECTOR columns, one being “dense” containing 20 dimensions of 64-bit floating point numbers, and the other column being a sparse vector of 35 8-bit signed integers:</p><pre class="op oq or os ot px py pz bp qa bb bk">create table vector_table (<br />    v64 vector(20, float64),<br />    v8  vector(35, int8, sparse)<br />)</pre><p id="ea02" class="pw-post-body-paragraph pe pf in pg b jl ph pi pj jo pk pl pm gn pn po pp gq pq pr ps gt pt pu pv pw ho bk">Oracle Database 23ai supports a number of advanced operations such as similarity searches on vector embeddings stored as the VECTOR data type. See the <a class="ag ha" href="https://docs.oracle.com/en/database/oracle/oracle-database/23/vecse/overview-ai-vector-search.html" rel="noopener ugc nofollow" target="_blank">Oracle AI Vector Search User’s Guide</a> for all the details.</p><p id="9ff9" class="pw-post-body-paragraph pe pf in pg b jl ph pi pj jo pk pl pm gn pn po pp gq pq pr ps gt pt pu pv pw ho bk">Here is a basic example in Go that uses godror 0.48 (or later). You also need Oracle Database 23.7 (or later). The code simply inserts and fetches vectors to show the godror side of working with them.</p><pre class="op oq or os ot px py pz bp qa bb bk">package mainimport (<br />  "context"<br />  "database/sql"<br />  "fmt"<br />  "github.com/godror/godror"<br />  "log"<br />  "math/rand/v2"<br />  "strconv"<br />  "time"<br />)// Generates a slice of random float32 numbers<br />func randomFloat32Slice(size int) []float32 {<br />  slice := make([]float32, size)<br />  for i := range slice {<br />    slice[i] = rand.Float32() * 10<br />  }<br />  return slice<br />}func main() {db, err := sql.Open("godror", ` user="scott" password="tiger" connectString="localhost/orclpdb1" `)<br />  if err != nil {<br />    log.Fatalf("Failed to connect to database: %v", err)<br />  }<br />  defer db.Close()ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)<br />  defer cancel()dropTable := `DROP TABLE IF EXISTS text_search`<br />  _, err = db.ExecContext(ctx, dropTable)// Create a table with VECTOR columns<br />  dimensions := 5<br />  createTable := `CREATE TABLE text_search (<br />      id NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,<br />      text_column CLOB NOT NULL,<br />      dense_embedding VECTOR(` + strconv.Itoa(dimensions) + `),<br />      sparse_embedding VECTOR(` + strconv.Itoa(dimensions) + `, FLOAT32, SPARSE))`<br />  _, err = db.ExecContext(ctx, createTable)<br />  if err != nil {<br />    log.Fatalf("Error creating table: %v", err)<br />  }<br />  fmt.Println("Table created successfully.")conn, err := db.Conn(ctx)<br />  if err != nil {<br />    log.Fatal(err)<br />  }<br />  defer conn.Close()stmt, err := conn.PrepareContext(ctx, `INSERT INTO text_search (text_column, dense_embedding, sparse_embedding)<br />      VALUES (:1,:2,:3)`)<br />  if err != nil {<br />    log.Fatal(err)<br />  }<br />  defer stmt.Close()// Insert some vector data<br />  float32Vector := godror.Vector{Values: randomFloat32Slice(dimensions)}<br />  sparseFloat32Vector := godror.Vector{Dimensions: uint32(dimensions), Indices: []uint32{0, 2, 4}, Values: randomFloat32Slice(3)}<br />  _, err = stmt.ExecContext(ctx, "SAMPLE TEXT1", &amp;float32Vector, &amp;sparseFloat32Vector)<br />  if err != nil {<br />    log.Fatal(err)<br />  }float32Vector = godror.Vector{Values: randomFloat32Slice(dimensions)}<br />  sparseFloat32Vector = godror.Vector{Dimensions: uint32(dimensions), Indices: []uint32{1, 3, 4}, Values: randomFloat32Slice(3)}<br />  _, err = stmt.ExecContext(ctx, "SAMPLE TEXT2", &amp;float32Vector, &amp;sparseFloat32Vector)<br />  if err != nil {<br />    log.Fatal(err)<br />  }<br />  fmt.Println("Inserted rows successfully.")// Query the vectors<br />  rows, err := conn.QueryContext(ctx, fmt.Sprintf(`<br />    SELECT id, text_column, dense_embedding, sparse_embedding from text_search`))<br />  if err != nil {<br />    log.Fatal("QueryContext failed: %v", err)<br />  }<br />  defer rows.Close()fmt.Println("Reading rows:")<br />  for rows.Next() {<br />    var outDenseEmbedding godror.Vector<br />    var outSparseEmbedding godror.Vector<br />    var outValue string<br />    var id godror.Number<br />    if err := rows.Scan(&amp;id, &amp;outValue, &amp;outDenseEmbedding, &amp;outSparseEmbedding); err != nil {<br />      log.Fatal("Scan failed: %v", err)<br />    }<br />    fmt.Printf("\tID:[%s], Text:[%s], Dense Embedding:[%v] and Sparse Embedding:[%v]\n",<br />      id, outValue, outDenseEmbedding.Values, outSparseEmbedding)<br />  }<br />}</pre><p id="2e52" class="pw-post-body-paragraph pe pf in pg b jl ph pi pj jo pk pl pm gn pn po pp gq pq pr ps gt pt pu pv pw ho bk">You can see it makes use of the new <code class="cx qh qi qj py b">godror.Vector()</code> struct.</p><p id="efa4" class="pw-post-body-paragraph pe pf in pg b jl ph pi pj jo pk pl pm gn pn po pp gq pq pr ps gt pt pu pv pw ho bk">The output will be:</p><pre class="op oq or os ot px py pz bp qa bb bk">Table created successfully.<br />Inserted rows successfully.<br />Reading rows:<br />  ID:[1], Text:[SAMPLE TEXT1], Dense Embedding:[[7.2318554 8.494286 2.4187808 5.6896343 1.2094277]] and Sparse Embedding:[{5 [0 2 4] [3.5823603 3.5613031 3.4197946] true}]<br />  ID:[2], Text:[SAMPLE TEXT2], Dense Embedding:[[8.704301 2.638142 5.376678 7.2791424 1.3518274]] and Sparse Embedding:[{5 [1 3 4] [6.7112656 5.6008286 0.21929502] true}]</pre><p id="1605" class="pw-post-body-paragraph pe pf in pg b jl ph pi pj jo pk pl pm gn pn po pp gq pq pr ps gt pt pu pv pw ho bk">You can easily extend the example to use the power of Oracle Database 23ai similarity searches.</p><p id="ab95" class="pw-post-body-paragraph pe pf in pg b jl ph pi pj jo pk pl pm gn pn po pp gq pq pr ps gt pt pu pv pw ho bk">Let us know how you use vectors in Go.</p></div></div>]]></description>
      <link>https://medium.com/oracledevs/the-go-godror-driver-now-supports-the-oracle-database-23ai-vector-data-type-8ab6f9cba31f?source=rss-adc937c3a9d------2</link>
      <guid>https://medium.com/oracledevs/the-go-godror-driver-now-supports-the-oracle-database-23ai-vector-data-type-8ab6f9cba31f?source=rss-adc937c3a9d------2</guid>
      <pubDate>Wed, 26 Mar 2025 10:16:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[How to create n8n workflows that connect to Oracle Database - Christopher Jones]]></title>
      <description><![CDATA[<div><div><h2 id="4686" class="pw-subtitle-paragraph jk im in bf b jl jm jn jo jp jq jr js jt ju jv jw jx jy jz cq du">The n8n workflow automation tool describes itself as “a workflow automation tool that combines AI capabilities with business process automation.” Several users have created modules for workflow nodes that connect to Oracle Database. Here I try one of them out for the first time.</h2><div></div><p id="b998" class="pw-post-body-paragraph om on in oo b jl op oq or jo os ot ou gn ov ow ox gq oy oz pa gt pb pc pd pe ho bk"><a class="ag ha" href="https://www.npmjs.com/package/n8n" rel="noopener ugc nofollow" target="_blank">n8n</a> requires a Node.js environment. I have this all set up locally so I followed the n8n instructions <a class="ag ha" href="https://docs.n8n.io/hosting/installation/npm/#install-globally-with-npm" rel="noopener ugc nofollow" target="_blank">Install globally with npm</a>. You may want to go down the <a class="ag ha" href="https://docs.n8n.io/hosting/installation/docker/" rel="noopener ugc nofollow" target="_blank">Docker</a> route instead.</p><p id="fd64" class="pw-post-body-paragraph om on in oo b jl op oq or jo os ot ou gn ov ow ox gq oy oz pa gt pb pc pd pe ho bk">I installed <code class="cx pf pg ph pi b">n8n</code> into Node.js using:</p><pre class="pj pk pl pm pn po pi pp bp pq bb bk">$ npm install n8n -g</pre><p id="d65b" class="pw-post-body-paragraph om on in oo b jl op oq or jo os ot ou gn ov ow ox gq oy oz pa gt pb pc pd pe ho bk">And then installed the <code class="cx pf pg ph pi b"><a class="ag ha" href="https://www.npmjs.com/package/n8n-nodes-oracle-database-parameterization" rel="noopener ugc nofollow" target="_blank">n8n-nodes-oracle-database-parameterization</a></code> module which seems to be the most advanced of the Oracle Database connectors. (Note this is a 3rd party module — Oracle does not contribute to it). Underneath, it does use Oracle’s <a class="ag ha" href="https://www.npmjs.com/package/oracledb" rel="noopener ugc nofollow" target="_blank">node-oracledb</a> driver:</p><pre class="pj pk pl pm pn po pi pp bp pq bb bk">$ npm install n8n-nodes-oracle-database-parameterization</pre><p id="7463" class="pw-post-body-paragraph om on in oo b jl op oq or jo os ot ou gn ov ow ox gq oy oz pa gt pb pc pd pe ho bk">Starting n8n was a simple matter of running:</p><pre class="pj pk pl pm pn po pi pp bp pq bb bk">$ export N8N_RUNNERS_ENABLED=true<br />$ export N8N_CUSTOM_EXTENSIONS=$(pwd)/node_modules/n8n-nodes-oracle-database-parameterization<br />$ n8n start</pre><p id="080c" class="pw-post-body-paragraph om on in oo b jl op oq or jo os ot ou gn ov ow ox gq oy oz pa gt pb pc pd pe ho bk">With this in place, I opened the default page http://localhost:5678 in my browser, and chose some credentials. The workflow pane then appeared:</p><figure class="pj pk pl pm pn qa px py paragraph-image"><div role="button" tabindex="0" class="qb qc fl qd bh qe"><div class="px py pz"><picture><source srcset="https://miro.medium.com/v2/resize:fit:640/format:webp/1*KzYYUFrMEMS66Y6iLiugAw.png 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/1*KzYYUFrMEMS66Y6iLiugAw.png 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/1*KzYYUFrMEMS66Y6iLiugAw.png 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/1*KzYYUFrMEMS66Y6iLiugAw.png 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/1*KzYYUFrMEMS66Y6iLiugAw.png 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/1*KzYYUFrMEMS66Y6iLiugAw.png 1100w, https://miro.medium.com/v2/resize:fit:1400/format:webp/1*KzYYUFrMEMS66Y6iLiugAw.png 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" type="image/webp" /><source data-testid="og" srcset="https://miro.medium.com/v2/resize:fit:640/1*KzYYUFrMEMS66Y6iLiugAw.png 640w, https://miro.medium.com/v2/resize:fit:720/1*KzYYUFrMEMS66Y6iLiugAw.png 720w, https://miro.medium.com/v2/resize:fit:750/1*KzYYUFrMEMS66Y6iLiugAw.png 750w, https://miro.medium.com/v2/resize:fit:786/1*KzYYUFrMEMS66Y6iLiugAw.png 786w, https://miro.medium.com/v2/resize:fit:828/1*KzYYUFrMEMS66Y6iLiugAw.png 828w, https://miro.medium.com/v2/resize:fit:1100/1*KzYYUFrMEMS66Y6iLiugAw.png 1100w, https://miro.medium.com/v2/resize:fit:1400/1*KzYYUFrMEMS66Y6iLiugAw.png 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" /></picture></div></div></figure><p id="3bc8" class="pw-post-body-paragraph om on in oo b jl op oq or jo os ot ou gn ov ow ox gq oy oz pa gt pb pc pd pe ho bk">To test out Oracle Database connectivity, I clicked on “Add first step…”. There are a lot of nodes that could be used!:</p><figure class="pj pk pl pm pn qa px py paragraph-image"><div role="button" tabindex="0" class="qb qc fl qd bh qe"><div class="px py pz"><picture><source srcset="https://miro.medium.com/v2/resize:fit:640/format:webp/1*9BB2p-h7L5MIy3INNTNgow.png 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/1*9BB2p-h7L5MIy3INNTNgow.png 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/1*9BB2p-h7L5MIy3INNTNgow.png 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/1*9BB2p-h7L5MIy3INNTNgow.png 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/1*9BB2p-h7L5MIy3INNTNgow.png 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/1*9BB2p-h7L5MIy3INNTNgow.png 1100w, https://miro.medium.com/v2/resize:fit:1400/format:webp/1*9BB2p-h7L5MIy3INNTNgow.png 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" type="image/webp" /><source data-testid="og" srcset="https://miro.medium.com/v2/resize:fit:640/1*9BB2p-h7L5MIy3INNTNgow.png 640w, https://miro.medium.com/v2/resize:fit:720/1*9BB2p-h7L5MIy3INNTNgow.png 720w, https://miro.medium.com/v2/resize:fit:750/1*9BB2p-h7L5MIy3INNTNgow.png 750w, https://miro.medium.com/v2/resize:fit:786/1*9BB2p-h7L5MIy3INNTNgow.png 786w, https://miro.medium.com/v2/resize:fit:828/1*9BB2p-h7L5MIy3INNTNgow.png 828w, https://miro.medium.com/v2/resize:fit:1100/1*9BB2p-h7L5MIy3INNTNgow.png 1100w, https://miro.medium.com/v2/resize:fit:1400/1*9BB2p-h7L5MIy3INNTNgow.png 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" /></picture></div></div></figure><p id="3cde" class="pw-post-body-paragraph om on in oo b jl op oq or jo os ot ou gn ov ow ox gq oy oz pa gt pb pc pd pe ho bk">I searched for Oracle. If you don’t see it, make sure that N8N_CUSTOM_EXTENSIONS is correctly set and restart n8n:</p><figure class="pj pk pl pm pn qa px py paragraph-image"><div role="button" tabindex="0" class="qb qc fl qd bh qe"><div class="px py pz"><picture><source srcset="https://miro.medium.com/v2/resize:fit:640/format:webp/1*yRWy3hn8ZKQ_rVop9P3MnA.png 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/1*yRWy3hn8ZKQ_rVop9P3MnA.png 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/1*yRWy3hn8ZKQ_rVop9P3MnA.png 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/1*yRWy3hn8ZKQ_rVop9P3MnA.png 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/1*yRWy3hn8ZKQ_rVop9P3MnA.png 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/1*yRWy3hn8ZKQ_rVop9P3MnA.png 1100w, https://miro.medium.com/v2/resize:fit:1400/format:webp/1*yRWy3hn8ZKQ_rVop9P3MnA.png 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" type="image/webp" /><source data-testid="og" srcset="https://miro.medium.com/v2/resize:fit:640/1*yRWy3hn8ZKQ_rVop9P3MnA.png 640w, https://miro.medium.com/v2/resize:fit:720/1*yRWy3hn8ZKQ_rVop9P3MnA.png 720w, https://miro.medium.com/v2/resize:fit:750/1*yRWy3hn8ZKQ_rVop9P3MnA.png 750w, https://miro.medium.com/v2/resize:fit:786/1*yRWy3hn8ZKQ_rVop9P3MnA.png 786w, https://miro.medium.com/v2/resize:fit:828/1*yRWy3hn8ZKQ_rVop9P3MnA.png 828w, https://miro.medium.com/v2/resize:fit:1100/1*yRWy3hn8ZKQ_rVop9P3MnA.png 1100w, https://miro.medium.com/v2/resize:fit:1400/1*yRWy3hn8ZKQ_rVop9P3MnA.png 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" /></picture></div></div></figure><p id="7a0e" class="pw-post-body-paragraph om on in oo b jl op oq or jo os ot ou gn ov ow ox gq oy oz pa gt pb pc pd pe ho bk">I selected it. As well as adding an Oracle Database node, this will automatically create a default trigger node to start the workflow on a user click.</p><p id="820b" class="pw-post-body-paragraph om on in oo b jl op oq or jo os ot ou gn ov ow ox gq oy oz pa gt pb pc pd pe ho bk">In the Oracle Database node pane I first clicked on “Select Credential”:</p><figure class="pj pk pl pm pn qa px py paragraph-image"><div role="button" tabindex="0" class="qb qc fl qd bh qe"><div class="px py pz"><picture><source srcset="https://miro.medium.com/v2/resize:fit:640/format:webp/1*kPsHtxjXiauwG6xtuEV7jQ.png 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/1*kPsHtxjXiauwG6xtuEV7jQ.png 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/1*kPsHtxjXiauwG6xtuEV7jQ.png 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/1*kPsHtxjXiauwG6xtuEV7jQ.png 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/1*kPsHtxjXiauwG6xtuEV7jQ.png 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/1*kPsHtxjXiauwG6xtuEV7jQ.png 1100w, https://miro.medium.com/v2/resize:fit:1400/format:webp/1*kPsHtxjXiauwG6xtuEV7jQ.png 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" type="image/webp" /><source data-testid="og" srcset="https://miro.medium.com/v2/resize:fit:640/1*kPsHtxjXiauwG6xtuEV7jQ.png 640w, https://miro.medium.com/v2/resize:fit:720/1*kPsHtxjXiauwG6xtuEV7jQ.png 720w, https://miro.medium.com/v2/resize:fit:750/1*kPsHtxjXiauwG6xtuEV7jQ.png 750w, https://miro.medium.com/v2/resize:fit:786/1*kPsHtxjXiauwG6xtuEV7jQ.png 786w, https://miro.medium.com/v2/resize:fit:828/1*kPsHtxjXiauwG6xtuEV7jQ.png 828w, https://miro.medium.com/v2/resize:fit:1100/1*kPsHtxjXiauwG6xtuEV7jQ.png 1100w, https://miro.medium.com/v2/resize:fit:1400/1*kPsHtxjXiauwG6xtuEV7jQ.png 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" /></picture></div></div></figure><p id="d839" class="pw-post-body-paragraph om on in oo b jl op oq or jo os ot ou gn ov ow ox gq oy oz pa gt pb pc pd pe ho bk">At the top I hovered over the “Oracle Credentials account” field and set a name “cj”:</p><figure class="pj pk pl pm pn qa px py paragraph-image"><div role="button" tabindex="0" class="qb qc fl qd bh qe"><div class="px py pz"><picture><source srcset="https://miro.medium.com/v2/resize:fit:640/format:webp/1*DagRx2A9ayQGTBzdtajaBQ.png 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/1*DagRx2A9ayQGTBzdtajaBQ.png 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/1*DagRx2A9ayQGTBzdtajaBQ.png 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/1*DagRx2A9ayQGTBzdtajaBQ.png 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/1*DagRx2A9ayQGTBzdtajaBQ.png 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/1*DagRx2A9ayQGTBzdtajaBQ.png 1100w, https://miro.medium.com/v2/resize:fit:1400/format:webp/1*DagRx2A9ayQGTBzdtajaBQ.png 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" type="image/webp" /><source data-testid="og" srcset="https://miro.medium.com/v2/resize:fit:640/1*DagRx2A9ayQGTBzdtajaBQ.png 640w, https://miro.medium.com/v2/resize:fit:720/1*DagRx2A9ayQGTBzdtajaBQ.png 720w, https://miro.medium.com/v2/resize:fit:750/1*DagRx2A9ayQGTBzdtajaBQ.png 750w, https://miro.medium.com/v2/resize:fit:786/1*DagRx2A9ayQGTBzdtajaBQ.png 786w, https://miro.medium.com/v2/resize:fit:828/1*DagRx2A9ayQGTBzdtajaBQ.png 828w, https://miro.medium.com/v2/resize:fit:1100/1*DagRx2A9ayQGTBzdtajaBQ.png 1100w, https://miro.medium.com/v2/resize:fit:1400/1*DagRx2A9ayQGTBzdtajaBQ.png 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" /></picture></div></div></figure><p id="dd68" class="pw-post-body-paragraph om on in oo b jl op oq or jo os ot ou gn ov ow ox gq oy oz pa gt pb pc pd pe ho bk">I then entered my database credentials and connection string, and clicked “Save”:</p><figure class="pj pk pl pm pn qa px py paragraph-image"><div role="button" tabindex="0" class="qb qc fl qd bh qe"><div class="px py pz"><picture><source srcset="https://miro.medium.com/v2/resize:fit:640/format:webp/1*BXXgoT4oXYaaZLH-re-Eng.png 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/1*BXXgoT4oXYaaZLH-re-Eng.png 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/1*BXXgoT4oXYaaZLH-re-Eng.png 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/1*BXXgoT4oXYaaZLH-re-Eng.png 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/1*BXXgoT4oXYaaZLH-re-Eng.png 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/1*BXXgoT4oXYaaZLH-re-Eng.png 1100w, https://miro.medium.com/v2/resize:fit:1400/format:webp/1*BXXgoT4oXYaaZLH-re-Eng.png 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" type="image/webp" /><source data-testid="og" srcset="https://miro.medium.com/v2/resize:fit:640/1*BXXgoT4oXYaaZLH-re-Eng.png 640w, https://miro.medium.com/v2/resize:fit:720/1*BXXgoT4oXYaaZLH-re-Eng.png 720w, https://miro.medium.com/v2/resize:fit:750/1*BXXgoT4oXYaaZLH-re-Eng.png 750w, https://miro.medium.com/v2/resize:fit:786/1*BXXgoT4oXYaaZLH-re-Eng.png 786w, https://miro.medium.com/v2/resize:fit:828/1*BXXgoT4oXYaaZLH-re-Eng.png 828w, https://miro.medium.com/v2/resize:fit:1100/1*BXXgoT4oXYaaZLH-re-Eng.png 1100w, https://miro.medium.com/v2/resize:fit:1400/1*BXXgoT4oXYaaZLH-re-Eng.png 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" /></picture></div></div></figure><p id="8dfc" class="pw-post-body-paragraph om on in oo b jl op oq or jo os ot ou gn ov ow ox gq oy oz pa gt pb pc pd pe ho bk">Back on the Oracle Database pane I entered a SQL statement, here a simple query from the EMP table:</p><figure class="pj pk pl pm pn qa px py paragraph-image"><div role="button" tabindex="0" class="qb qc fl qd bh qe"><div class="px py pz"><picture><source srcset="https://miro.medium.com/v2/resize:fit:640/format:webp/1*rm5p4E50z-C4b2Q2yQy0LA.png 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/1*rm5p4E50z-C4b2Q2yQy0LA.png 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/1*rm5p4E50z-C4b2Q2yQy0LA.png 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/1*rm5p4E50z-C4b2Q2yQy0LA.png 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/1*rm5p4E50z-C4b2Q2yQy0LA.png 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/1*rm5p4E50z-C4b2Q2yQy0LA.png 1100w, https://miro.medium.com/v2/resize:fit:1400/format:webp/1*rm5p4E50z-C4b2Q2yQy0LA.png 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" type="image/webp" /><source data-testid="og" srcset="https://miro.medium.com/v2/resize:fit:640/1*rm5p4E50z-C4b2Q2yQy0LA.png 640w, https://miro.medium.com/v2/resize:fit:720/1*rm5p4E50z-C4b2Q2yQy0LA.png 720w, https://miro.medium.com/v2/resize:fit:750/1*rm5p4E50z-C4b2Q2yQy0LA.png 750w, https://miro.medium.com/v2/resize:fit:786/1*rm5p4E50z-C4b2Q2yQy0LA.png 786w, https://miro.medium.com/v2/resize:fit:828/1*rm5p4E50z-C4b2Q2yQy0LA.png 828w, https://miro.medium.com/v2/resize:fit:1100/1*rm5p4E50z-C4b2Q2yQy0LA.png 1100w, https://miro.medium.com/v2/resize:fit:1400/1*rm5p4E50z-C4b2Q2yQy0LA.png 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" /></picture></div></div></figure><p id="c9b3" class="pw-post-body-paragraph om on in oo b jl op oq or jo os ot ou gn ov ow ox gq oy oz pa gt pb pc pd pe ho bk">I didn’t add any parameters. I also left the Settings tab unchanged:</p><figure class="pj pk pl pm pn qa px py paragraph-image"><div role="button" tabindex="0" class="qb qc fl qd bh qe"><div class="px py pz"><picture><source srcset="https://miro.medium.com/v2/resize:fit:640/format:webp/1*ks8CubgPYxvuQan0foBJ5Q.png 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/1*ks8CubgPYxvuQan0foBJ5Q.png 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/1*ks8CubgPYxvuQan0foBJ5Q.png 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/1*ks8CubgPYxvuQan0foBJ5Q.png 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/1*ks8CubgPYxvuQan0foBJ5Q.png 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/1*ks8CubgPYxvuQan0foBJ5Q.png 1100w, https://miro.medium.com/v2/resize:fit:1400/format:webp/1*ks8CubgPYxvuQan0foBJ5Q.png 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" type="image/webp" /><source data-testid="og" srcset="https://miro.medium.com/v2/resize:fit:640/1*ks8CubgPYxvuQan0foBJ5Q.png 640w, https://miro.medium.com/v2/resize:fit:720/1*ks8CubgPYxvuQan0foBJ5Q.png 720w, https://miro.medium.com/v2/resize:fit:750/1*ks8CubgPYxvuQan0foBJ5Q.png 750w, https://miro.medium.com/v2/resize:fit:786/1*ks8CubgPYxvuQan0foBJ5Q.png 786w, https://miro.medium.com/v2/resize:fit:828/1*ks8CubgPYxvuQan0foBJ5Q.png 828w, https://miro.medium.com/v2/resize:fit:1100/1*ks8CubgPYxvuQan0foBJ5Q.png 1100w, https://miro.medium.com/v2/resize:fit:1400/1*ks8CubgPYxvuQan0foBJ5Q.png 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" /></picture></div></div></figure><p id="96fe" class="pw-post-body-paragraph om on in oo b jl op oq or jo os ot ou gn ov ow ox gq oy oz pa gt pb pc pd pe ho bk">Clicking “Test step” produced output, here shown in Tabular form on the right. (N8n also allows you to see the same output as JSON or in a schema form):</p><figure class="pj pk pl pm pn qa px py paragraph-image"><div role="button" tabindex="0" class="qb qc fl qd bh qe"><div class="px py pz"><picture><source srcset="https://miro.medium.com/v2/resize:fit:640/format:webp/1*8HqTqbpV2rYtRlS2TMSznQ.png 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/1*8HqTqbpV2rYtRlS2TMSznQ.png 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/1*8HqTqbpV2rYtRlS2TMSznQ.png 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/1*8HqTqbpV2rYtRlS2TMSznQ.png 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/1*8HqTqbpV2rYtRlS2TMSznQ.png 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/1*8HqTqbpV2rYtRlS2TMSznQ.png 1100w, https://miro.medium.com/v2/resize:fit:1400/format:webp/1*8HqTqbpV2rYtRlS2TMSznQ.png 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" type="image/webp" /><source data-testid="og" srcset="https://miro.medium.com/v2/resize:fit:640/1*8HqTqbpV2rYtRlS2TMSznQ.png 640w, https://miro.medium.com/v2/resize:fit:720/1*8HqTqbpV2rYtRlS2TMSznQ.png 720w, https://miro.medium.com/v2/resize:fit:750/1*8HqTqbpV2rYtRlS2TMSznQ.png 750w, https://miro.medium.com/v2/resize:fit:786/1*8HqTqbpV2rYtRlS2TMSznQ.png 786w, https://miro.medium.com/v2/resize:fit:828/1*8HqTqbpV2rYtRlS2TMSznQ.png 828w, https://miro.medium.com/v2/resize:fit:1100/1*8HqTqbpV2rYtRlS2TMSznQ.png 1100w, https://miro.medium.com/v2/resize:fit:1400/1*8HqTqbpV2rYtRlS2TMSznQ.png 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" /></picture></div></div></figure><p id="c4cb" class="pw-post-body-paragraph om on in oo b jl op oq or jo os ot ou gn ov ow ox gq oy oz pa gt pb pc pd pe ho bk">Back on the workflow pane I decided to add another Oracle node, by clicking on the “+” sign and again searching for “Oracle” in the node list:</p><figure class="pj pk pl pm pn qa px py paragraph-image"><div role="button" tabindex="0" class="qb qc fl qd bh qe"><div class="px py pz"><picture><source srcset="https://miro.medium.com/v2/resize:fit:640/format:webp/1*Nwx-ATlwdxKM1qwiznmV7A.png 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/1*Nwx-ATlwdxKM1qwiznmV7A.png 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/1*Nwx-ATlwdxKM1qwiznmV7A.png 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/1*Nwx-ATlwdxKM1qwiznmV7A.png 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/1*Nwx-ATlwdxKM1qwiznmV7A.png 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/1*Nwx-ATlwdxKM1qwiznmV7A.png 1100w, https://miro.medium.com/v2/resize:fit:1400/format:webp/1*Nwx-ATlwdxKM1qwiznmV7A.png 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" type="image/webp" /><source data-testid="og" srcset="https://miro.medium.com/v2/resize:fit:640/1*Nwx-ATlwdxKM1qwiznmV7A.png 640w, https://miro.medium.com/v2/resize:fit:720/1*Nwx-ATlwdxKM1qwiznmV7A.png 720w, https://miro.medium.com/v2/resize:fit:750/1*Nwx-ATlwdxKM1qwiznmV7A.png 750w, https://miro.medium.com/v2/resize:fit:786/1*Nwx-ATlwdxKM1qwiznmV7A.png 786w, https://miro.medium.com/v2/resize:fit:828/1*Nwx-ATlwdxKM1qwiznmV7A.png 828w, https://miro.medium.com/v2/resize:fit:1100/1*Nwx-ATlwdxKM1qwiznmV7A.png 1100w, https://miro.medium.com/v2/resize:fit:1400/1*Nwx-ATlwdxKM1qwiznmV7A.png 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" /></picture></div></div></figure><p id="bd06" class="pw-post-body-paragraph om on in oo b jl op oq or jo os ot ou gn ov ow ox gq oy oz pa gt pb pc pd pe ho bk">In this node I queried the DEPT table using bind variable placeholders:</p><figure class="pj pk pl pm pn qa px py paragraph-image"><div role="button" tabindex="0" class="qb qc fl qd bh qe"><div class="px py pz"><picture><source srcset="https://miro.medium.com/v2/resize:fit:640/format:webp/1*a5M60iygzaMeAT75JHj9jw.png 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/1*a5M60iygzaMeAT75JHj9jw.png 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/1*a5M60iygzaMeAT75JHj9jw.png 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/1*a5M60iygzaMeAT75JHj9jw.png 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/1*a5M60iygzaMeAT75JHj9jw.png 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/1*a5M60iygzaMeAT75JHj9jw.png 1100w, https://miro.medium.com/v2/resize:fit:1400/format:webp/1*a5M60iygzaMeAT75JHj9jw.png 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" type="image/webp" /><source data-testid="og" srcset="https://miro.medium.com/v2/resize:fit:640/1*a5M60iygzaMeAT75JHj9jw.png 640w, https://miro.medium.com/v2/resize:fit:720/1*a5M60iygzaMeAT75JHj9jw.png 720w, https://miro.medium.com/v2/resize:fit:750/1*a5M60iygzaMeAT75JHj9jw.png 750w, https://miro.medium.com/v2/resize:fit:786/1*a5M60iygzaMeAT75JHj9jw.png 786w, https://miro.medium.com/v2/resize:fit:828/1*a5M60iygzaMeAT75JHj9jw.png 828w, https://miro.medium.com/v2/resize:fit:1100/1*a5M60iygzaMeAT75JHj9jw.png 1100w, https://miro.medium.com/v2/resize:fit:1400/1*a5M60iygzaMeAT75JHj9jw.png 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" /></picture></div></div></figure><p id="1a11" class="pw-post-body-paragraph om on in oo b jl op oq or jo os ot ou gn ov ow ox gq oy oz pa gt pb pc pd pe ho bk">To assign values to those placeholders, I clicked “Add Parameter”, set the placeholder name “en”, and simply dragged from the word “DEPTNO” in the “rows” column on the left, into the parameter “Value” field. N8n automatically changed the field to the appropriate syntax, and changed the type to an expression. This connects the output from the workflow’s previous node into the current one:</p><figure class="pj pk pl pm pn qa px py paragraph-image"><div role="button" tabindex="0" class="qb qc fl qd bh qe"><div class="px py pz"><picture><source srcset="https://miro.medium.com/v2/resize:fit:640/format:webp/1*ZvB5zt8whOIN7ri_Y0KlFg.png 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/1*ZvB5zt8whOIN7ri_Y0KlFg.png 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/1*ZvB5zt8whOIN7ri_Y0KlFg.png 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/1*ZvB5zt8whOIN7ri_Y0KlFg.png 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/1*ZvB5zt8whOIN7ri_Y0KlFg.png 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/1*ZvB5zt8whOIN7ri_Y0KlFg.png 1100w, https://miro.medium.com/v2/resize:fit:1400/format:webp/1*ZvB5zt8whOIN7ri_Y0KlFg.png 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" type="image/webp" /><source data-testid="og" srcset="https://miro.medium.com/v2/resize:fit:640/1*ZvB5zt8whOIN7ri_Y0KlFg.png 640w, https://miro.medium.com/v2/resize:fit:720/1*ZvB5zt8whOIN7ri_Y0KlFg.png 720w, https://miro.medium.com/v2/resize:fit:750/1*ZvB5zt8whOIN7ri_Y0KlFg.png 750w, https://miro.medium.com/v2/resize:fit:786/1*ZvB5zt8whOIN7ri_Y0KlFg.png 786w, https://miro.medium.com/v2/resize:fit:828/1*ZvB5zt8whOIN7ri_Y0KlFg.png 828w, https://miro.medium.com/v2/resize:fit:1100/1*ZvB5zt8whOIN7ri_Y0KlFg.png 1100w, https://miro.medium.com/v2/resize:fit:1400/1*ZvB5zt8whOIN7ri_Y0KlFg.png 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" /></picture></div></div></figure><p id="7abc" class="pw-post-body-paragraph om on in oo b jl op oq or jo os ot ou gn ov ow ox gq oy oz pa gt pb pc pd pe ho bk">I added a parameter and did the same for the second bind variable placeholder “dno”, dragging the text “DEPTNO” from the left into the Values field:</p><figure class="pj pk pl pm pn qa px py paragraph-image"><div role="button" tabindex="0" class="qb qc fl qd bh qe"><div class="px py pz"><picture><source srcset="https://miro.medium.com/v2/resize:fit:640/format:webp/1*0Qa8ZAlDoOCUJTXoTvZBwA.png 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/1*0Qa8ZAlDoOCUJTXoTvZBwA.png 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/1*0Qa8ZAlDoOCUJTXoTvZBwA.png 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/1*0Qa8ZAlDoOCUJTXoTvZBwA.png 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/1*0Qa8ZAlDoOCUJTXoTvZBwA.png 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/1*0Qa8ZAlDoOCUJTXoTvZBwA.png 1100w, https://miro.medium.com/v2/resize:fit:1400/format:webp/1*0Qa8ZAlDoOCUJTXoTvZBwA.png 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" type="image/webp" /><source data-testid="og" srcset="https://miro.medium.com/v2/resize:fit:640/1*0Qa8ZAlDoOCUJTXoTvZBwA.png 640w, https://miro.medium.com/v2/resize:fit:720/1*0Qa8ZAlDoOCUJTXoTvZBwA.png 720w, https://miro.medium.com/v2/resize:fit:750/1*0Qa8ZAlDoOCUJTXoTvZBwA.png 750w, https://miro.medium.com/v2/resize:fit:786/1*0Qa8ZAlDoOCUJTXoTvZBwA.png 786w, https://miro.medium.com/v2/resize:fit:828/1*0Qa8ZAlDoOCUJTXoTvZBwA.png 828w, https://miro.medium.com/v2/resize:fit:1100/1*0Qa8ZAlDoOCUJTXoTvZBwA.png 1100w, https://miro.medium.com/v2/resize:fit:1400/1*0Qa8ZAlDoOCUJTXoTvZBwA.png 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" /></picture></div></div></figure><p id="236d" class="pw-post-body-paragraph om on in oo b jl op oq or jo os ot ou gn ov ow ox gq oy oz pa gt pb pc pd pe ho bk">Note n8n-nodes-oracle-database-parameterization only supports String and Number binds.</p><p id="9103" class="pw-post-body-paragraph om on in oo b jl op oq or jo os ot ou gn ov ow ox gq oy oz pa gt pb pc pd pe ho bk">Testing the step showed the query from DEPT worked:</p><figure class="pj pk pl pm pn qa px py paragraph-image"><div role="button" tabindex="0" class="qb qc fl qd bh qe"><div class="px py pz"><picture><source srcset="https://miro.medium.com/v2/resize:fit:640/format:webp/1*jhkNWVu4P2q5kSEcZrYjYg.png 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/1*jhkNWVu4P2q5kSEcZrYjYg.png 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/1*jhkNWVu4P2q5kSEcZrYjYg.png 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/1*jhkNWVu4P2q5kSEcZrYjYg.png 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/1*jhkNWVu4P2q5kSEcZrYjYg.png 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/1*jhkNWVu4P2q5kSEcZrYjYg.png 1100w, https://miro.medium.com/v2/resize:fit:1400/format:webp/1*jhkNWVu4P2q5kSEcZrYjYg.png 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" type="image/webp" /><source data-testid="og" srcset="https://miro.medium.com/v2/resize:fit:640/1*jhkNWVu4P2q5kSEcZrYjYg.png 640w, https://miro.medium.com/v2/resize:fit:720/1*jhkNWVu4P2q5kSEcZrYjYg.png 720w, https://miro.medium.com/v2/resize:fit:750/1*jhkNWVu4P2q5kSEcZrYjYg.png 750w, https://miro.medium.com/v2/resize:fit:786/1*jhkNWVu4P2q5kSEcZrYjYg.png 786w, https://miro.medium.com/v2/resize:fit:828/1*jhkNWVu4P2q5kSEcZrYjYg.png 828w, https://miro.medium.com/v2/resize:fit:1100/1*jhkNWVu4P2q5kSEcZrYjYg.png 1100w, https://miro.medium.com/v2/resize:fit:1400/1*jhkNWVu4P2q5kSEcZrYjYg.png 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" /></picture></div></div></figure><p id="5b74" class="pw-post-body-paragraph om on in oo b jl op oq or jo os ot ou gn ov ow ox gq oy oz pa gt pb pc pd pe ho bk">Let’s add a third node, this time one that inserts data into the database. But first, behind the scenes I created a table “t” using SQL*Plus:</p><pre class="pj pk pl pm pn po pi pp bp pq bb bk">SQL&gt; create table t (name varchar2(10), department varchar2(13));</pre><p id="a2b9" class="pw-post-body-paragraph om on in oo b jl op oq or jo os ot ou gn ov ow ox gq oy oz pa gt pb pc pd pe ho bk">In the workflow pane I again searched for “Oracle” and selected it:</p><figure class="pj pk pl pm pn qa px py paragraph-image"><div role="button" tabindex="0" class="qb qc fl qd bh qe"><div class="px py pz"><picture><source srcset="https://miro.medium.com/v2/resize:fit:640/format:webp/1*HZxYYbqtml9HYQE69H6obQ.png 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/1*HZxYYbqtml9HYQE69H6obQ.png 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/1*HZxYYbqtml9HYQE69H6obQ.png 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/1*HZxYYbqtml9HYQE69H6obQ.png 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/1*HZxYYbqtml9HYQE69H6obQ.png 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/1*HZxYYbqtml9HYQE69H6obQ.png 1100w, https://miro.medium.com/v2/resize:fit:1400/format:webp/1*HZxYYbqtml9HYQE69H6obQ.png 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" type="image/webp" /><source data-testid="og" srcset="https://miro.medium.com/v2/resize:fit:640/1*HZxYYbqtml9HYQE69H6obQ.png 640w, https://miro.medium.com/v2/resize:fit:720/1*HZxYYbqtml9HYQE69H6obQ.png 720w, https://miro.medium.com/v2/resize:fit:750/1*HZxYYbqtml9HYQE69H6obQ.png 750w, https://miro.medium.com/v2/resize:fit:786/1*HZxYYbqtml9HYQE69H6obQ.png 786w, https://miro.medium.com/v2/resize:fit:828/1*HZxYYbqtml9HYQE69H6obQ.png 828w, https://miro.medium.com/v2/resize:fit:1100/1*HZxYYbqtml9HYQE69H6obQ.png 1100w, https://miro.medium.com/v2/resize:fit:1400/1*HZxYYbqtml9HYQE69H6obQ.png 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" /></picture></div></div></figure><p id="d9cf" class="pw-post-body-paragraph om on in oo b jl op oq or jo os ot ou gn ov ow ox gq oy oz pa gt pb pc pd pe ho bk">In the Oracle Database pane I entered the SQL INSERT statement and created the first bind variable placeholder “n”, setting its value by dragging the left hand text NAME to the Value field:</p><figure class="pj pk pl pm pn qa px py paragraph-image"><div role="button" tabindex="0" class="qb qc fl qd bh qe"><div class="px py pz"><picture><source srcset="https://miro.medium.com/v2/resize:fit:640/format:webp/1*15f68fxSP3YZy9__M1bJNA.png 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/1*15f68fxSP3YZy9__M1bJNA.png 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/1*15f68fxSP3YZy9__M1bJNA.png 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/1*15f68fxSP3YZy9__M1bJNA.png 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/1*15f68fxSP3YZy9__M1bJNA.png 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/1*15f68fxSP3YZy9__M1bJNA.png 1100w, https://miro.medium.com/v2/resize:fit:1400/format:webp/1*15f68fxSP3YZy9__M1bJNA.png 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" type="image/webp" /><source data-testid="og" srcset="https://miro.medium.com/v2/resize:fit:640/1*15f68fxSP3YZy9__M1bJNA.png 640w, https://miro.medium.com/v2/resize:fit:720/1*15f68fxSP3YZy9__M1bJNA.png 720w, https://miro.medium.com/v2/resize:fit:750/1*15f68fxSP3YZy9__M1bJNA.png 750w, https://miro.medium.com/v2/resize:fit:786/1*15f68fxSP3YZy9__M1bJNA.png 786w, https://miro.medium.com/v2/resize:fit:828/1*15f68fxSP3YZy9__M1bJNA.png 828w, https://miro.medium.com/v2/resize:fit:1100/1*15f68fxSP3YZy9__M1bJNA.png 1100w, https://miro.medium.com/v2/resize:fit:1400/1*15f68fxSP3YZy9__M1bJNA.png 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" /></picture></div></div></figure><p id="0f20" class="pw-post-body-paragraph om on in oo b jl op oq or jo os ot ou gn ov ow ox gq oy oz pa gt pb pc pd pe ho bk">The second bind variable placeholder “d” was added and its value set by dragging DNAME to the appropriate Values field:</p><figure class="pj pk pl pm pn qa px py paragraph-image"><div role="button" tabindex="0" class="qb qc fl qd bh qe"><div class="px py pz"><picture><source srcset="https://miro.medium.com/v2/resize:fit:640/format:webp/1*BOwk4QcgzVVf2XpPyYd8zA.png 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/1*BOwk4QcgzVVf2XpPyYd8zA.png 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/1*BOwk4QcgzVVf2XpPyYd8zA.png 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/1*BOwk4QcgzVVf2XpPyYd8zA.png 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/1*BOwk4QcgzVVf2XpPyYd8zA.png 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/1*BOwk4QcgzVVf2XpPyYd8zA.png 1100w, https://miro.medium.com/v2/resize:fit:1400/format:webp/1*BOwk4QcgzVVf2XpPyYd8zA.png 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" type="image/webp" /><source data-testid="og" srcset="https://miro.medium.com/v2/resize:fit:640/1*BOwk4QcgzVVf2XpPyYd8zA.png 640w, https://miro.medium.com/v2/resize:fit:720/1*BOwk4QcgzVVf2XpPyYd8zA.png 720w, https://miro.medium.com/v2/resize:fit:750/1*BOwk4QcgzVVf2XpPyYd8zA.png 750w, https://miro.medium.com/v2/resize:fit:786/1*BOwk4QcgzVVf2XpPyYd8zA.png 786w, https://miro.medium.com/v2/resize:fit:828/1*BOwk4QcgzVVf2XpPyYd8zA.png 828w, https://miro.medium.com/v2/resize:fit:1100/1*BOwk4QcgzVVf2XpPyYd8zA.png 1100w, https://miro.medium.com/v2/resize:fit:1400/1*BOwk4QcgzVVf2XpPyYd8zA.png 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" /></picture></div></div></figure><p id="53f3" class="pw-post-body-paragraph om on in oo b jl op oq or jo os ot ou gn ov ow ox gq oy oz pa gt pb pc pd pe ho bk">Testing the step shows that one row was inserted:</p><figure class="pj pk pl pm pn qa px py paragraph-image"><div role="button" tabindex="0" class="qb qc fl qd bh qe"><div class="px py pz"><picture><source srcset="https://miro.medium.com/v2/resize:fit:640/format:webp/1*88Zp2wFQIfrQN_1W3AL8PA.png 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/1*88Zp2wFQIfrQN_1W3AL8PA.png 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/1*88Zp2wFQIfrQN_1W3AL8PA.png 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/1*88Zp2wFQIfrQN_1W3AL8PA.png 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/1*88Zp2wFQIfrQN_1W3AL8PA.png 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/1*88Zp2wFQIfrQN_1W3AL8PA.png 1100w, https://miro.medium.com/v2/resize:fit:1400/format:webp/1*88Zp2wFQIfrQN_1W3AL8PA.png 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" type="image/webp" /><source data-testid="og" srcset="https://miro.medium.com/v2/resize:fit:640/1*88Zp2wFQIfrQN_1W3AL8PA.png 640w, https://miro.medium.com/v2/resize:fit:720/1*88Zp2wFQIfrQN_1W3AL8PA.png 720w, https://miro.medium.com/v2/resize:fit:750/1*88Zp2wFQIfrQN_1W3AL8PA.png 750w, https://miro.medium.com/v2/resize:fit:786/1*88Zp2wFQIfrQN_1W3AL8PA.png 786w, https://miro.medium.com/v2/resize:fit:828/1*88Zp2wFQIfrQN_1W3AL8PA.png 828w, https://miro.medium.com/v2/resize:fit:1100/1*88Zp2wFQIfrQN_1W3AL8PA.png 1100w, https://miro.medium.com/v2/resize:fit:1400/1*88Zp2wFQIfrQN_1W3AL8PA.png 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" /></picture></div></div></figure><p id="68ce" class="pw-post-body-paragraph om on in oo b jl op oq or jo os ot ou gn ov ow ox gq oy oz pa gt pb pc pd pe ho bk">This was easily verified in SQL*Plus. The data has been inserted and committed:</p><pre class="pj pk pl pm pn po pi pp bp pq bb bk">SQL&gt; select * from t;NAME       DEPARTMENT<br />---------- -------------<br />SCOTT      RESEARCH</pre><p id="b27b" class="pw-post-body-paragraph om on in oo b jl op oq or jo os ot ou gn ov ow ox gq oy oz pa gt pb pc pd pe ho bk">Here is the final workflow. Yes mine is all Oracle Database, but n8n has many pre-supplied nodes that you can add to your own workflows:</p><figure class="pj pk pl pm pn qa px py paragraph-image"><div role="button" tabindex="0" class="qb qc fl qd bh qe"><div class="px py pz"><picture><source srcset="https://miro.medium.com/v2/resize:fit:640/format:webp/1*GBa1gbklMF8TMRKEzaEAJA.png 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/1*GBa1gbklMF8TMRKEzaEAJA.png 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/1*GBa1gbklMF8TMRKEzaEAJA.png 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/1*GBa1gbklMF8TMRKEzaEAJA.png 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/1*GBa1gbklMF8TMRKEzaEAJA.png 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/1*GBa1gbklMF8TMRKEzaEAJA.png 1100w, https://miro.medium.com/v2/resize:fit:1400/format:webp/1*GBa1gbklMF8TMRKEzaEAJA.png 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" type="image/webp" /><source data-testid="og" srcset="https://miro.medium.com/v2/resize:fit:640/1*GBa1gbklMF8TMRKEzaEAJA.png 640w, https://miro.medium.com/v2/resize:fit:720/1*GBa1gbklMF8TMRKEzaEAJA.png 720w, https://miro.medium.com/v2/resize:fit:750/1*GBa1gbklMF8TMRKEzaEAJA.png 750w, https://miro.medium.com/v2/resize:fit:786/1*GBa1gbklMF8TMRKEzaEAJA.png 786w, https://miro.medium.com/v2/resize:fit:828/1*GBa1gbklMF8TMRKEzaEAJA.png 828w, https://miro.medium.com/v2/resize:fit:1100/1*GBa1gbklMF8TMRKEzaEAJA.png 1100w, https://miro.medium.com/v2/resize:fit:1400/1*GBa1gbklMF8TMRKEzaEAJA.png 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" /></picture></div></div></figure><p id="9d49" class="pw-post-body-paragraph om on in oo b jl op oq or jo os ot ou gn ov ow ox gq oy oz pa gt pb pc pd pe ho bk">I hope this post has given you enough information to get started with n8n and Oracle Database. The only special step was installing an appropriate Oracle module, and setting N8N_CUSTOM_EXTENSIONS.</p><h1 id="6088" class="qg ps in bf qh qi qj jn gk qk ql jq gm qm qn qo qp qq qr qs qt qu qv qw qx qy bk">node-oracledb Resources</h1><ul class=""><li id="a33f" class="om on in oo b jl qz oq or jo ra ot ou gn rb ow ox gq rc oz pa gt rd pc pd pe re rf rg bk">Node-oracledb installation instructions are <a class="ag ha" href="https://node-oracledb.readthedocs.io/en/latest/user_guide/installation.html" rel="noopener ugc nofollow" target="_blank">here</a>.</li><li id="c45a" class="om on in oo b jl rh oq or jo ri ot ou gn rj ow ox gq rk oz pa gt rl pc pd pe re rf rg bk">Node-oracledb documentation is <a class="ag ha" href="https://node-oracledb.readthedocs.io/en/latest/" rel="noopener ugc nofollow" target="_blank">here</a>.</li><li id="159b" class="om on in oo b jl rh oq or jo ri ot ou gn rj ow ox gq rk oz pa gt rl pc pd pe re rf rg bk">Node-oracledb change log is <a class="ag ha" href="https://node-oracledb.readthedocs.io/en/latest/release_notes.html" rel="noopener ugc nofollow" target="_blank">here</a>.</li><li id="691f" class="om on in oo b jl rh oq or jo ri ot ou gn rj ow ox gq rk oz pa gt rl pc pd pe re rf rg bk">Issues and questions about node-oracledb can be posted on <a class="ag ha" href="https://github.com/oracle/node-oracledb/issues" rel="noopener ugc nofollow" target="_blank">GitHub</a> or <a class="ag ha" href="https://node-oracledb.slack.com/" rel="noopener ugc nofollow" target="_blank">Slack</a> (<a class="ag ha" href="https://join.slack.com/t/node-oracledb/shared_invite/enQtNDU4Mjc2NzM5OTA2LWMzY2ZlZDY5MDdlMGZiMGRkY2IzYjI5OGU4YTEzZWM5YjQ3ODUzMjcxNWQyNzE4MzM5YjNkYjVmNDk5OWU5NDM" rel="noopener ugc nofollow" target="_blank">link to join Slack</a>).</li></ul></div></div>]]></description>
      <link>https://medium.com/oracledevs/how-to-create-n8n-workflows-that-connect-to-oracle-database-8f930834df82?source=rss-adc937c3a9d------2</link>
      <guid>https://medium.com/oracledevs/how-to-create-n8n-workflows-that-connect-to-oracle-database-8f930834df82?source=rss-adc937c3a9d------2</guid>
      <pubDate>Wed, 26 Mar 2025 09:31:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[Unicode Collation Sorting - Derick Rethans]]></title>
      <description><![CDATA[<p>I recently added support to this website to receive Favourites and Replies through the ActivityPub posts that I create from each article.</p><p>Replies show up as comments after moderation, and favourites show up as Likes under each of the articles.</p><p>When fetching all the likes, my internal API returns the following structure — just like how <a href="https://www.php.net/manual/en/pdostatement.fetchall.php">PDOStatement::fetchAll()</a> returns them:</p><pre>array(7) {
  [0]=&gt;
  array(8) {
    ["name"]=&gt;
    string(14) "Marcus Bointon"
    ["linked_account"]=&gt;
    string(33) "https://phpc.social/users/Synchro"
  }
  [1]=&gt;
  array(8) {
    ["name"]=&gt;
    string(14) "Derick Rethans"
    ["linked_account"]=&gt;
    string(33) "https://phpc.social/users/derickr"
  }
  [2]=&gt;
  array(8) {
    ["name"]=&gt;
    string(26) "🇵🇸 Álvaro González"
    ["linked_account"]=&gt;
    string(37) "https://mastodon.social/users/kAlvaro"
  }
}
</pre><p>I wanted to sort the <em>likes</em> by name, which turned out harder to be than I had hoped. Mostly because people do odd things with their names sometimes, such as not using an upper-case letter, or by prefixing their names with emojis as you can see in the example above.</p><p>If each entry in my array was only a string with a name, and no emoji is prefixed, you can use <a href="https://www.php.net/manual/en/function.natcasesort.php">natcasesort()</a>, but I have both complex objects and an emoji. This means PHP's built-in functions don't cut it.</p><p>However, PHP also has the <strong>Intl</strong> extension, which has a <a href="https://www.php.net/manual/en/class.collator.php">Collator</a> class with a <a href="https://www.php.net/manual/en/collator.sort.php">sort</a> method.</p><p>To create such a collator in code, use:</p><pre>$collator = new Collator('root');
</pre><p>The <a href="http://www.unicode.org/reports/tr35/tr35-collation.html#Root_Collation">Root Collation</a> is ICU's <a href="https://www.unicode.org/reports/tr10/#Default_Unicode_Collation_Element_Table">Default Collation</a>, but as the ICU documentation says:</p><blockquote>
<p>Not all languages have sorting sequences that correspond with the root collation order because no single sort order can simultaneously encompass the specifics of all the languages. In particular, languages that share a script may sort the same letters differently.</p>
</blockquote><p>This is good enough for my use case there, where I only want to sort names in a reasonable fashion.</p><p>One thing that it <strong>does</strong> do is to sort lower-case letters before upper-case letters, but this behaviour can be changed by setting <a href="https://www.php.net/manual/en/class.collator.php#collator.constants.case-first">CASE_FIRST</a> attribute on the collator to <a href="https://www.php.net/manual/en/class.collator.php#collator.constants.upper-first">UPPER_FIRST</a>:</p><pre>$collator-&gt;setAttribute(Collator::CASE_FIRST, Collator::UPPER_FIRST);
</pre><p>Letters in non-Latin script will sort after the Latin letters.</p><p>However, the <code>Collator-&gt;sort()</code> method can only handle arrays of strings, and not complex objects.</p><p>To get around this limitation we instead use PHP's built-in <a href="https://www.php.net/usort">usort()</a> function with our own callback. In our callback we can use the <a href="https://www.php.net/collator-getsortkey">Collator::getSortKey()</a> method on each sort element's <code>name</code> array key to create the key that <code>Collator::sort()</code> would have used internally.</p><p>For good measure, we also use <a href="https://www.php.net/trim">trim</a> to remove preceding and trailing whitespace. The code to sort the elements now looks like:</p><pre>$col = new Collator('root');
$col-&gt;setAttribute(Collator::CASE_FIRST, Collator::UPPER_FIRST);
usort(
    $allLikes,
    function($a, $b) use ($col) {
        $aName = trim($a['name']);
        $bName = trim($b['name']);
        $aKey = $col-&gt;getSortKey($aName);
        $bKey = $col-&gt;getSortKey($bName);
        return $aKey &lt;=&gt; $bKey;
    }
);
</pre><p>Now the only problem is that emojis sort before actual letters, so we need to scrub them. Each letter defined in the Unicode standard has properties associated with it. One of those properties is the <a href="https://www.unicode.org/reports/tr42/#d1e3191">General Category</a>. If you examine the <a href="https://www.unicode.org/Public/UCD/latest/ucd/UnicodeData.txt">chart</a> you will fined that for <code>0061;LATIN SMALL LETTER A</code> the GC is <code>Ll</code> (Letter, Lower-case). The flag emoji from my example is composed of two characters: <code>1F1F5;REGIONAL INDICATOR SYMBOL LETTER P</code> and <code>1F1F8;REGIONAL INDICATOR SYMBOL LETTER S</code>. Both of these have as category <code>So</code> (Symbol, Other).</p><p>The PCRE library that PHP uses for regular expressions is aware of these categories, and you can select for for them with the <code>\p{…}</code> specifier. The <a href="https://www.php.net/manual/en/regexp.reference.unicode.php">documentation</a> has a page on it.</p><p>In our case we want to remove all Symbols (with category <code>S</code>). Changing our <code>trim</code> lines to strip this character class accomplishes this.</p><p>When we now combine all of this, we get:</p><pre>&lt;?php
$allLikes = [
    [ 'name' =&gt; 'Marcus Bointon', 'linked_account' =&gt; 'https://phpc.social/users/Synchro' ],
    [ 'name' =&gt; 'Derick Rethans', 'linked_account' =&gt; 'https://phpc.social/users/derickr' ],
    [ 'name' =&gt; '🇵🇸 Álvaro González', 'linked_account' =&gt; 'https://mastodon.social/users/kAlvaro' ],
];
$col = new Collator('root');
$col-&gt;setAttribute(Collator::CASE_FIRST, Collator::UPPER_FIRST);
usort(
    $allLikes,
    function($a, $b) use ($col) {
        $aName = trim(preg_replace('/\p{S}+/u', '', $a['name']));
        $bName = trim(preg_replace('/\p{S}+/u', '', $b['name']));
        $aKey = $col-&gt;getSortKey($aName);
        $bKey = $col-&gt;getSortKey($bName);
        return $aKey &lt;=&gt; $bKey;
    }
);
var_dump($allLikes);
?&gt;
</pre><p>When we now run the example with the <code>$allLikes</code> array from previously, our result is:</p><pre>array(3) {
  [0] =&gt;
  array(2) {
    'name' =&gt;
    string(26) "🇵🇸 Álvaro González"
    'linked_account' =&gt;
    string(37) "https://mastodon.social/users/kAlvaro"
  }
  [1] =&gt;
  array(2) {
    'name' =&gt;
    string(14) "Derick Rethans"
    'linked_account' =&gt;
    string(33) "https://phpc.social/users/derickr"
  }
  [2] =&gt;
  array(2) {
    'name' =&gt;
    string(14) "Marcus Bointon"
    'linked_account' =&gt;
    string(33) "https://phpc.social/users/Synchro"
  }
}
</pre><p>And from that, I can then generate the HTML code to render who liked my article, which you can hopefully see below.</p>]]></description>
      <link>https://derickrethans.nl/unicode-collation-sorting.html</link>
      <guid>https://derickrethans.nl/unicode-collation-sorting.html</guid>
      <pubDate>Tue, 25 Mar 2025 15:50:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[Self hosted photo albums - Larry Garfield]]></title>
      <description><![CDATA[<p>I've long kept my photo backups off of Google Cloud. I've never trusted them to keep them safe, and I've never trusted them to not do something with them I didn't want. Like, say, ingest them into AI training without telling me. (Which, now, everyone is doing.) Instead, I've backed up my photos to my own <a rel="noopener noreferrer" target="_blank" href="https://nextcloud.com/">Nextcloud</a> server, manually organized them, and let them get backed up from there.</p><p>More recently, I've decided I really need a proper photo album tool to carry around "wallet photos" of family and such to show people. A few years back I started building my own application for that in Symfony 4, but I ran into some walls and eventually abandoned the effort. This time, I figured I'd see what was available on the market for self-hosted photo albums for me and my family to use.</p><p>Strap yourself in, because this is a really depressing story (with a happy ending, at least).</p><p>I reviewed 7 self-hosted photo album tools, after checking various review sites for their top-ten lists. Of those 7:</p><ul><li>3 were in PHP, 2 were in JavaScript or TypeScript, and 2 were in Go.</li>
<li>2 used the MIT license, 2 used the GPL, 1 used AGPL, and two had broken non-free licenses.</li>
<li>I managed to get one working. 1. Uno.</li>
<li>Most really pushed you to use their Docker Compose setup to install, none of which actually worked.</li>
</ul><p>Let's have a look at the mess directly.</p><p>Language: TypeScript License: MIT</p><p>PiGallery 2 is intended as a light-weight, directory-based photo album. The recommended way to install it is to use their Docker compose file and nginx conf file... which you have to just manually copy out of Git. (Seriously?) And when I tried to get that to run locally, I could never connect to it successfully. There was something weird with the port configuration, and I wasn't able to quickly figure it out. If I can't get the "easy" install to work, I'm not interested.</p><p>Language: PHP/MySQL License: GPLv2</p><p>Unlike many on here it doesn't provide a Docker image, which is fine so I set one up using <a rel="noopener noreferrer" target="_blank" href="http://phpdocker.io">phpdocker.io</a>. Unfortunately, it's net installer crashed when I tried to use it, without useful errors. Trying to install manually resulted in PHP null-value errors from the install script. When I looked at the install script, I found dozens upon dozens of file system operations with the <code>@</code> operator on them to hide errors.</p><p>At that point I gave up on Piwigo.</p><p>Language: PHP/MySQL License: GPL, version unspecified</p><p>When I first visted the Coppermine website, I got an error that their TLS certificate had expired a week and a half before. How reassuring.</p><p>Skipping past that, I was greeted with a website with minuscule text, with a design dating from the Clinton presidency. How reassuring.</p><p>Right on the home page, it says Coppermine is compatible all the way down to PHP 4.2, and supposedly up to 8.2. For those not familiar with PHP, 4.2 was released in 2002, only slightly after the Clinton presidency. PHP has evolved, um, a lot in 22 years, and most developers today view PHP 4 as an embarrassment to be forgotten. If their code is still designed to run on 4.2, it means they're ignoring literally 20 years of language improvements, including security improvements. How reassuring.</p><p>Oh, and the installation instructions, linked in the menu, are a direct link to some random forum post from 2017. How reassuring.</p><p>At this point I was so reassured that I Noped right out and didn't even bother trying to install it.</p><p>Language: JavaScript. (Not TypeScript, raw JS as far as I can tell.) License: None specified.</p><p>Although this app showed up on a few top-ten lists, its license is not specified, and installation only offers Windows and Mac. (Really?) The "others" section eventually lets you get to an Ubuntu section, where their recommendation is to install it via... an Apt remote. Which is an interesting choice.</p><p>It has a GitHub repo, but that has no license listed at all. Which technically means it's not licensed at all, and so downloading it is a felony. (Yes, copyright law is like that.)</p><p>Being a good Netizen, I reached out to the company through their Contact form to ask them to clarify. They eventually responded that, despite some parts of the code being in public GitHub repos, none of it is Open Source.</p><p>Noping right out of that one.</p><p>Language: Go License: It's complicated</p><p>I actually managed to get this one to run! This one also "installs" via Docker Compose, but it actually worked. This is the only one of the apps I reviewed that I could get to work. Mind you, as a Go app I cannot fathom why it needs a container to run, since Go compiles to a single binary.</p><p>Their system requirements are absurdly high. Quoting from their site, "you should host PhotoPrism on a server with <strong>at least 2 cores</strong>, <strong>3 GB of physical memory</strong>,<a rel="noopener noreferrer" target="_blank" href="https://docs.photoprism.app/getting-started/#fn:1">1</a> and a 64-bit operating system." What the heck are they doing? It's Go, not the JVM.</p><p>In quick experimentation, it seemed decent enough. The interface is snappy and supports uploading directly from the browser.</p><p>However, I then ran into a pickle. The GitHub repository says the license is AGPL, which I am fine with. However, in the app itself is a License page that is not even remotely close to Free Software anything, listing mainly all the ways you cannot modify or redistribute the code.</p><p>I filed <a rel="noopener noreferrer" target="_blank" href="https://github.com/photoprism/photoprism/issues/4609">an issue</a> on their repository about it, and got back a rather blunt comment that only the "Community Edition" is AGPL, which is a different download. The supported version is not.</p><p>Noping right out of this one, too.</p><p>Language: Go, with TypeScript for front-end License: AGPLv3</p><p>Another app wants you install via Docker Compose. And when I tried to do so, I got a bunch of errors about undefined environment variables. The install documentation says nothing about setting them, and it's not clear how to do so, so at this point I gave up.</p><p>Language: PHP License: MIT</p><p>Lychee is built with Laravel, which I don't care for but I have used very good Laravel-based apps in the past so I had high hopes. It talks about using Docker, but unlike the others here doesn't provide a docker-compose file, just some very long Docker run commands.</p><p>Their primary instructions are to git-clone the project, then run <code>composer install</code> and <code>npm</code>. Unfortunately, phpdocker.io is still built using Ubuntu 22.04, which has an ancient version of npm in it, and I didn't want to bother trying to figure out how to upgrade it.</p><p>Lychee did offer a demo container, which uses SQLite. That I was able to get to run successfully. However, for unclear reasons it wouldn't actually show any images.</p><p>At this point, I gave up.</p><p>Rather disappointed in the state of the art, I decided to take a different approach. As I mentioned, I use Nextcloud to store all my images. Nextcloud has a photo app, but the last time I used it, it was very basic, and pretty bad. That was a few years ago, though, so I went searching.</p><p>Turns out, not only has Nextcloud Photos improved considerably, there's also another extension app on it called <a rel="noopener noreferrer" target="_blank" href="https://apps.nextcloud.com/apps/memories">Memories</a>. On paper, it looks like it does everything I'm after. A timeline feed, custom albums that don't require duplicating files, you can edit the Exif data of the image to show a title and description, plus some fancy extras like mapping geo information to OpenStreetMap and AI-based tagging, if you have the right additional apps installed. So would it work?</p><p>Turns out... yes. The setup was slightly fiddly, but mostly because it took a while to download all the map data and index a half-million photos. Once it did that, though... it just worked. It does almost everything I was looking for. I haven't figured out how to reorder albums or pictures within an album, and it looks like it doesn't support sub-albums. But otherwise, it does what I need. It even has a mobile app (free) that let's me show off selected pictures on my phone, which is what I was ultimately after.</p><p>I have always had a love/hate relationship with Nextcloud. In concept, I love it. Self-hosted file server and application hub? Sign me up! Despite being a PHP dev of 25 years, I've never quite understood why PHP made sense for it, though. And upgrades have always been a pain, and frequently break. But its functionality is just so useful. Apps are hit or miss, ranging from first-rate (like Memories) to meh.</p><p>But in this case, it ended up being both the cleanest and most capable option, as well as the easiest to get going, provided I already had a Nextcloud server. So, solution found. I am now a Memories user, and will be setting up accounts for the rest of the family, too.</p>]]></description>
      <link>https://www.garfieldtech.com/blog/photo-albums</link>
      <guid>https://www.garfieldtech.com/blog/photo-albums</guid>
      <pubDate>Tue, 12 Nov 2024 23:22:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[PHP 8.4.0 RC4 available for testing - PHP: Hypertext Preprocessor]]></title>
      <description><![CDATA[<div id="intro" class="clearfix container hero"><img class="hero__logo" src="https://www.php.net/images/logos/php-logo-white.svg" alt="php" width="240" height="120" /><p class="hero__text">A <strong>popular general-purpose scripting language</strong> that is especially suited to web development.<br />Fast, flexible and pragmatic, PHP powers everything from your blog to the most popular websites in the world.</p><p><a href="https://www.php.net/releases/8.3/index.php" class="hero__btn hero__btn--primary">What's new in 8.3</a> <a href="https://www.php.net/downloads.php" class="hero__btn hero__btn--secondary">Download</a></p><ul class="hero__versions"><li class="hero__version"><a class="hero__version-link" href="https://www.php.net/downloads.php#v8.3.13">8.3.13</a> · <a class="notes" href="https://www.php.net/ChangeLog-8.php#8.3.13">Changelog</a> · <a class="notes" href="https://www.php.net/migration83">Upgrading</a></li>
<li class="hero__version"><a class="hero__version-link" href="https://www.php.net/downloads.php#v8.2.25">8.2.25</a> · <a class="notes" href="https://www.php.net/ChangeLog-8.php#8.2.25">Changelog</a> · <a class="notes" href="https://www.php.net/migration82">Upgrading</a></li>
<li class="hero__version"><a class="hero__version-link" href="https://www.php.net/downloads.php#v8.1.30">8.1.30</a> · <a class="notes" href="https://www.php.net/ChangeLog-8.php#8.1.30">Changelog</a> · <a class="notes" href="https://www.php.net/migration81">Upgrading</a></li>
</ul></div><div id="layout" class="clearfix"><section id="layout-content"><div class="home-content"><article class="newsentry"><header class="title"><time datetime="2024-11-07T18:53:19+00:00">07 Nov 2024</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the release of PHP 8.4.0, RC4. This is the fourth release candidate, continuing the PHP 8.4 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php84">PHP Wiki</a>.</p><p>For source downloads of PHP 8.4.0, RC4 please visit the <a href="https://downloads.php.net/~calvinb">download page</a>.</p><p>Please carefully test this version and report any issues found in the <a href="https://github.com/php/php-src/issues">bug reporting system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.4.0RC4/NEWS">NEWS</a> file or the <a href="https://github.com/php/php-src/blob/php-8.4.0RC4/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be the production-ready, general availability release, planned for 21 November 2021.</p><p>The signatures for the release can be found in <a href="https://gist.github.com/NattyNarwhal/6a107fe3b862ac3e2cf03b013e151eba">the manifest</a> or on <a href="https://qa.php.net/">the QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></article><article class="newsentry"><header class="title"><time datetime="2024-10-24T13:22:16+00:00">24 Oct 2024</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the release of PHP 8.4.0, RC3. This is the third release candidate, continuing the PHP 8.4 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php84">PHP Wiki</a>.</p><p>For source downloads of PHP 8.4.0, RC3 please visit the <a href="https://downloads.php.net/~saki">download page</a>.</p><p>Please carefully test this version and report any issues found in the <a href="https://github.com/php/php-src/issues">bug reporting system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.4.0RC3/NEWS">NEWS</a> file or the <a href="https://github.com/php/php-src/blob/php-8.4.0RC3/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be RC 4, planned for 07 November 2024.</p><p>The signatures for the release can be found in <a href="https://gist.github.com/SakiTakamachi/3648bbdbfeadefb8e40b4ad9592d3b6a">the manifest</a> or on <a href="https://qa.php.net/">the QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></article><article class="newsentry"><header class="title"><time datetime="2024-10-24T12:54:49+00:00">24 Oct 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.25. This is a bug fix release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.25 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.25">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2024-10-24T12:05:52+00:00">24 Oct 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.3.13. This is a bug fix release.</p><p>All PHP 8.3 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.3.13 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.3.13">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2024-10-10T14:04:23+00:00">10 Oct 2024</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the release of PHP 8.4.0, RC2. This is the second release candidate, continuing the PHP 8.4 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php84">PHP Wiki</a>.</p><p>For source downloads of PHP 8.4.0, RC2 please visit the <a href="https://downloads.php.net/~calvinb">download page</a>.</p><p>Please carefully test this version and report any issues found in the <a href="https://github.com/php/php-src/issues">bug reporting system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.4.0RC2/NEWS">NEWS</a> file or the <a href="https://github.com/php/php-src/blob/php-8.4.0RC2/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be RC 3, planned for 24 October 2024.</p><p>The signatures for the release can be found in <a href="https://gist.github.com/NattyNarwhal/ea2bb82ce1e3fb67f385b2d6e2e085dc">the manifest</a> or on <a href="https://qa.php.net/">the QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></article><article class="newsentry"><header class="title"><time datetime="2024-09-26T19:56:50+00:00">26 Sep 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.1.30. This is a security release.</p><p>All PHP 8.1 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.1.30 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.1.30">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2024-09-26T19:25:27+00:00">26 Sep 2024</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the release of PHP 8.4.0, RC 1. This is the first release candidate, continuing the PHP 8.4 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php84">PHP Wiki</a>.</p><p>For source downloads of PHP 8.4.0, RC 1 please visit the <a href="https://downloads.php.net/~saki">download page</a>.</p><p>Please carefully test this version and report any issues found in the <a href="https://github.com/php/php-src/issues">bug reporting system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.4.0RC1/NEWS">NEWS</a> file or the <a href="https://github.com/php/php-src/blob/php-8.4.0RC1/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be RC 2, planned for 10 October 2024.</p><p>The signatures for the release can be found in <a href="https://gist.github.com/SakiTakamachi/198dac0514f8cba37ed3506526cd1fb2">the manifest</a> or on <a href="https://qa.php.net/">the QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></article><article class="newsentry"><header class="title"><time datetime="2024-09-26T16:25:23+00:00">26 Sep 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.24. This is a security release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.24 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.24">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2024-09-26T13:31:15+00:00">26 Sep 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.3.12. This is a security release.</p><p>All PHP 8.3 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.3.12 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.3.12">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2024-09-12T14:14:49+00:00">12 Sep 2024</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the release of PHP 8.4.0, Beta 5. This is the third beta release, continuing the PHP 8.4 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php84">PHP Wiki</a>.</p><p>For source downloads of PHP 8.4.0, Beta 5 please visit the <a href="https://downloads.php.net/~calvinb">download page</a>.</p><p>Please carefully test this version and report any issues found in the <a href="https://github.com/php/php-src/issues">bug reporting system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.4.0beta5/NEWS">NEWS</a> file or the <a href="https://github.com/php/php-src/blob/php-8.4.0beta5/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be RC 1, planned for 26 September 2024.</p><p>The signatures for the release can be found in <a href="https://gist.github.com/NattyNarwhal/2dc0c8a3f7bf63ec5143b4bf703ee626">the manifest</a> or on <a href="https://qa.php.net/">the QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></article><article class="newsentry"><header class="title"><time datetime="2024-08-29T21:40:58+00:00">29 Aug 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.3.11. This is a bug fix release.</p><p>All PHP 8.3 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.3.11 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.3.11">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2024-08-29T18:15:12+00:00">29 Aug 2024</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the release of PHP 8.4.0, Beta 4. This is the second beta release, continuing the PHP 8.4 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php84">PHP Wiki</a>.</p><p>For source downloads of PHP 8.4.0, Beta 4 please visit the <a href="https://downloads.php.net/~saki">download page</a>.</p><p>Please carefully test this version and report any issues found in the <a href="https://github.com/php/php-src/issues">bug reporting system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.4.0beta4/NEWS">NEWS</a> file or the <a href="https://github.com/php/php-src/blob/php-8.4.0beta4/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be Beta 5, planned for 12 September 2024.</p><p>The signatures for the release can be found in <a href="https://gist.github.com/SakiTakamachi/7132a67e0cdc1e792fa1e88f1726d5cc">the manifest</a> or on <a href="https://qa.php.net/">the QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></article><article class="newsentry"><header class="title"><time datetime="2024-08-29T15:58:02+00:00">29 Aug 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.23. This is a bug fix release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.23 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.23">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2024-08-15T13:45:25+00:00">15 Aug 2024</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the release of PHP 8.4.0, Beta 3. This is the first beta release, continuing the PHP 8.4 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php84">PHP Wiki</a>.</p><p>For source downloads of PHP 8.4.0, Beta 3 please visit the <a href="https://downloads.php.net/~calvinb">download page</a>.</p><p>Please carefully test this version and report any issues found in the <a href="https://github.com/php/php-src/issues">bug reporting system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.4.0beta3/NEWS">NEWS</a> file or the <a href="https://github.com/php/php-src/blob/php-8.4.0beta3/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be Beta 4, planned for 29 August 2024.</p><p>The signatures for the release can be found in <a href="https://gist.github.com/NattyNarwhal/fdd2de9d3b165143d376679258811c15">the manifest</a> or on <a href="https://qa.php.net/">the QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></article><article class="newsentry"><header class="title"><time datetime="2024-08-01T23:21:43+00:00">01 Aug 2024</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the second testing release of PHP 8.4.0, Alpha 4. This continues the PHP 8.4 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php84">PHP Wiki</a>.</p><p>For source downloads of PHP 8.4.0 Alpha 4 please visit the <a href="https://downloads.php.net/~saki/">download page</a>.</p><p>Please carefully test this version and report any issues found in the <a href="https://github.com/php/php-src/issues">bug reporting system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.4.0alpha4/NEWS">NEWS</a> file, or the <a href="https://github.com/php/php-src/blob/php-8.4.0alpha4/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be Beta 1, planned for 15 Aug 2024.</p><p>The signatures for the release can be found in <a href="https://gist.github.com/SakiTakamachi/6ef16057e96947aa030408db244718a7">the manifest</a> or on <a href="https://qa.php.net/">the QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></article><article class="newsentry"><header class="title"><time datetime="2024-08-01T16:12:06+00:00">01 Aug 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.22. This is a bug fix release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.22 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.22">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2024-08-01T13:28:53+00:00">01 Aug 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.3.10. This is a bug fix release.</p><p>All PHP 8.3 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.3.10 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.3.10">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2024-07-18T13:30:46+00:00">18 Jul 2024</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the second testing release of PHP 8.4.0, Alpha 2. This continues the PHP 8.4 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php84">PHP Wiki</a>.</p><p>For source downloads of PHP 8.4.0 Alpha 2 please visit the <a href="https://downloads.php.net/~calvinb/">download page</a>.</p><p>Please carefully test this version and report any issues found in the <a href="https://github.com/php/php-src/issues">bug reporting system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.4.0alpha2/NEWS">NEWS</a> file, or the <a href="https://github.com/php/php-src/blob/php-8.4.0alpha2/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be Alpha 3, planned for 1 Aug 2024.</p><p>The signatures for the release can be found in <a href="https://gist.github.com/NattyNarwhal/74b55b8fcc6411ff8db05f87a6f41864">the manifest</a> or on <a href="https://qa.php.net/">the QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></article><article class="newsentry"><header class="title"><time datetime="2024-07-05T13:22:12+00:00">05 Jul 2024</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the first testing release of PHP 8.4.0, Alpha 1. This starts the PHP 8.4 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php84">PHP Wiki</a>.</p><p>For source downloads of PHP 8.4.0 Alpha 1 please visit the <a href="https://downloads.php.net/~saki/">download page</a>.</p><p>Please carefully test this version and report any issues found using <a href="https://github.com/php/php-src/issues">the bug tracking system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.4.0alpha1/NEWS">NEWS</a> file, or the <a href="https://github.com/php/php-src/blob/php-8.4.0alpha1/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be Alpha 2, planned for 18 Jul 2024.</p><p>The signatures for the release can be found in the <a href="https://gist.github.com/SakiTakamachi/d3e32b780590319bee72d8402593a3ca">manifest</a> or on the <a href="https://qa.php.net/">QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></article><article class="newsentry"><header class="title"><time datetime="2024-07-04T22:59:58+00:00">04 Jul 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.3.9. This is a bug fix release.</p><p>All PHP 8.3 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.3.9 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.3.9">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2024-07-04T14:43:24+00:00">04 Jul 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.21. This is a bug fix release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.21 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.21">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2024-06-06T14:56:47+00:00">06 Jun 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.20. This is a security release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.20 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.20">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2024-06-06T14:42:14+00:00">06 Jun 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.3.8. This is a security release.</p><p>All PHP 8.3 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.3.8 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.3.8">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2024-06-06T14:12:51+00:00">06 Jun 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.1.29. This is a security release.</p><p>All PHP 8.1 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.1.29 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.1.29">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2024-05-09T14:40:06+00:00">09 May 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.3.7. This is a bug fix release.</p><p>All PHP 8.3 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.3.7 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.3.7">ChangeLog</a>.</p></div></article></div></section><aside class="tips"><div class="inner"><div class="panel"><div class="body"><p>The PHP Foundation is a collective of people and organizations, united in the mission to ensure the long-term prosperity of the PHP language.</p><p><a href="https://thephp.foundation/donate/" class="btn btn-primary">Donate</a></p></div></div><p class="panel"><a href="https://www.php.net/cal.php">User Group Events</a></p><p class="panel"><a href="https://www.php.net/thanks.php">Special Thanks</a></p></div>
</aside></div>]]></description>
      <link>https://www.php.net/index.php#2024-11-07-1</link>
      <guid>https://www.php.net/index.php#2024-11-07-1</guid>
      <pubDate>Thu, 07 Nov 2024 01:00:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[Xdebug Update: October 2024 - Derick Rethans]]></title>
      <description><![CDATA[<p>In this monthly update I explain what happened with Xdebug development</p><p><a href="https://github.com/sponsors/derickr/">GitHub</a> and <a href="https://xdebug.org/support">Pro/Business supporters</a> will get it earlier, around the first of each month.</p><p>On GitHub sponsors, I am currently 31% towards my $2,500 per month goal, which is set to allow continued <strong>maintenance</strong> of Xdebug. This is again less than last month.</p><p>If you are leading a team or company, then it is also possible to support Xdebug through <a href="https://xdebug.org/support">a subscription</a>.</p><p>In the last month, I spend around 10 hours on Xdebug, with 19 hours funded. I also spent 16 hours on the Native Path Mapping project.</p><div class="articleSubSection"><h2>PHP 8.4</h2><p>I made the first beta release of Xdebug 3.4 that is compatible with PHP 8.4, which is due to be released on November 21st. I hope to have a GA release of Xdebug 3.4.0 out around that date too.</p><p>Beyond making that beta release, I have also looked into many bug reports, and fixed a few bugs.</p><p>As side-project to the new PIE installer, which is expected to replace PECL in the near future, a new Windows extension build action for GitHub actions has been created. I have been evaluating that, and provided some feedback. This is not quite ready for prime time, and I am not sure yet whether I will be able to use that for the 3.4 releases.</p></div><div class="articleSubSection"><h2>Native Xdebug Path Mapping</h2><p>I also continued with the <a href="https://xdebug.org/funding/001-native-path-mapping">Native Xdebug Path Mapping</a> project.</p><p>This is a separately funded project, I don't classify the hours that I worked on this in "Xdebug Hours". I also publish a separate report on the <a href="https://xdebug.org/funding/001-native-path-mapping">project page</a>.</p><p>In short, I have finished the parser, and also made some performance improvements in the way I store data internally. I dive into the depths of that in its <a href="https://xdebug.org/funding/001-native-path-mapping/updates/2024-11-01">dedicated report</a>.</p><p>I am now working on integrating it into Xdebug, and realised that there is one thing that I had forgotten to add, and that is a reverse mapping. The algorithms can only map remote a file/line to a local file/line, but in order to be able for an IDE to set a breakpoint on a local file line (which is how you would edit it), it also needs to have a reverse map.</p><p>By the end of this month I hope to have a working version to try out, but it will likely not be in the Xdebug 3.4 release, as that has to be released near when PHP 8.4 is released.</p></div><div class="articleSubSection"><h2>Xdebug Videos</h2><p>I have created no new videos since last month, but you can see all the previous ones on my <a href="https://www.youtube.com/playlist?list=PLg9Kjjye-m1g_eXpdaifUqLqALLqZqKd4">channel</a>.</p><p>If you have any suggestions, feel free to reach out to <a href="https://phpc.social/@derickr">me on Mastodon</a> or via <a href="http://derickrethans/who.html">email</a>.</p></div><div class="articleSubSection"><h2>Business Supporter Scheme and Funding</h2><p>In the last month, no new business supporters signed up.</p><p>Besides business support, I also maintain a <a href="https://www.patreon.com/derickr">Patreon</a> page, a profile on <a href="https://github.com/sponsors/derickr">GitHub sponsors</a>, as well as an <a href="https://opencollective.com/xdebug">OpenCollective</a> organisation.</p><p>If you want to contribute to specific projects, you can find those on the <a href="https://xdebug.org/funding">Projects</a> page.</p></div><div class="articleSubSection"><h2>Xdebug Cloud</h2><p>Xdebug Cloud is the <em>Proxy As A Service</em> platform to allow for debugging in more scenarios, where it is hard, or impossible, to have Xdebug make a connection to the IDE. It is continuing to operate as Beta release.</p><p>Packages start at £49/month, and I have recently introduced a package for larger companies. This has a larger initial set of tokens, and discounted extra tokens.</p><p>If you want to be kept up to date with Xdebug Cloud, please sign up to the <a href="https://xdebug.cloud/newsletter">mailinglist</a>, which I will use to send out an update not more than once a month.</p></div>]]></description>
      <link>https://derickrethans.nl/xdebug-update-october-2024.html</link>
      <guid>https://derickrethans.nl/xdebug-update-october-2024.html</guid>
      <pubDate>Tue, 05 Nov 2024 11:10:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[PHP 8.4.0 RC3 available for testing - PHP: Hypertext Preprocessor]]></title>
      <description><![CDATA[<div id="intro" class="clearfix container hero"><img class="hero-logo" src="https://www.php.net/images/logos/php-logo-white.svg" alt="php" width="240" height="120" /><p class="hero-text">A <strong>popular general-purpose scripting language</strong> that is especially suited to web development.<br />Fast, flexible and pragmatic, PHP powers everything from your blog to the most popular websites in the world.</p><p><a href="https://www.php.net/releases/8.3/index.php" class="hero-btn hero-btn-primary">What's new in 8.3</a> <a href="https://www.php.net/downloads.php" class="hero-btn hero-btn-secondary">Download</a></p><ul class="hero-versions"><li class="hero-version"><a class="hero-version-link" href="https://www.php.net/downloads.php#v8.3.13">8.3.13</a> · <a class="notes" href="https://www.php.net/ChangeLog-8.php#8.3.13">Changelog</a> · <a class="notes" href="https://www.php.net/migration83">Upgrading</a></li>
<li class="hero-version"><a class="hero-version-link" href="https://www.php.net/downloads.php#v8.2.25">8.2.25</a> · <a class="notes" href="https://www.php.net/ChangeLog-8.php#8.2.25">Changelog</a> · <a class="notes" href="https://www.php.net/migration82">Upgrading</a></li>
<li class="hero-version"><a class="hero-version-link" href="https://www.php.net/downloads.php#v8.1.30">8.1.30</a> · <a class="notes" href="https://www.php.net/ChangeLog-8.php#8.1.30">Changelog</a> · <a class="notes" href="https://www.php.net/migration81">Upgrading</a></li>
</ul></div><div id="layout" class="clearfix"><section id="layout-content"><div class="home-content"><article class="newsentry"><header class="title"><time datetime="2024-10-24T13:22:16+00:00">24 Oct 2024</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the release of PHP 8.4.0, RC3. This is the third release candidate, continuing the PHP 8.4 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php84">PHP Wiki</a>.</p><p>For source downloads of PHP 8.4.0, RC3 please visit the <a href="https://downloads.php.net/~saki">download page</a>.</p><p>Please carefully test this version and report any issues found in the <a href="https://github.com/php/php-src/issues">bug reporting system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.4.0RC3/NEWS">NEWS</a> file or the <a href="https://github.com/php/php-src/blob/php-8.4.0RC3/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be RC 4, planned for 07 November 2024.</p><p>The signatures for the release can be found in <a href="https://gist.github.com/SakiTakamachi/3648bbdbfeadefb8e40b4ad9592d3b6a">the manifest</a> or on <a href="https://qa.php.net/">the QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></article><article class="newsentry"><header class="title"><time datetime="2024-10-24T12:54:49+00:00">24 Oct 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.25. This is a bug fix release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.25 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.25">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2024-10-24T12:05:52+00:00">24 Oct 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.3.13. This is a bug fix release.</p><p>All PHP 8.3 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.3.13 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.3.13">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2024-10-10T14:04:23+00:00">10 Oct 2024</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the release of PHP 8.4.0, RC2. This is the second release candidate, continuing the PHP 8.4 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php84">PHP Wiki</a>.</p><p>For source downloads of PHP 8.4.0, RC2 please visit the <a href="https://downloads.php.net/~calvinb">download page</a>.</p><p>Please carefully test this version and report any issues found in the <a href="https://github.com/php/php-src/issues">bug reporting system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.4.0RC2/NEWS">NEWS</a> file or the <a href="https://github.com/php/php-src/blob/php-8.4.0RC2/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be RC 3, planned for 24 October 2024.</p><p>The signatures for the release can be found in <a href="https://gist.github.com/NattyNarwhal/ea2bb82ce1e3fb67f385b2d6e2e085dc">the manifest</a> or on <a href="https://qa.php.net/">the QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></article><article class="newsentry"><header class="title"><time datetime="2024-09-26T19:56:50+00:00">26 Sep 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.1.30. This is a security release.</p><p>All PHP 8.1 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.1.30 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.1.30">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2024-09-26T19:25:27+00:00">26 Sep 2024</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the release of PHP 8.4.0, RC 1. This is the first release candidate, continuing the PHP 8.4 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php84">PHP Wiki</a>.</p><p>For source downloads of PHP 8.4.0, RC 1 please visit the <a href="https://downloads.php.net/~saki">download page</a>.</p><p>Please carefully test this version and report any issues found in the <a href="https://github.com/php/php-src/issues">bug reporting system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.4.0RC1/NEWS">NEWS</a> file or the <a href="https://github.com/php/php-src/blob/php-8.4.0RC1/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be RC 2, planned for 10 October 2024.</p><p>The signatures for the release can be found in <a href="https://gist.github.com/SakiTakamachi/198dac0514f8cba37ed3506526cd1fb2">the manifest</a> or on <a href="https://qa.php.net/">the QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></article><article class="newsentry"><header class="title"><time datetime="2024-09-26T16:25:23+00:00">26 Sep 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.24. This is a security release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.24 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.24">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2024-09-26T13:31:15+00:00">26 Sep 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.3.12. This is a security release.</p><p>All PHP 8.3 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.3.12 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.3.12">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2024-09-12T14:14:49+00:00">12 Sep 2024</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the release of PHP 8.4.0, Beta 5. This is the third beta release, continuing the PHP 8.4 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php84">PHP Wiki</a>.</p><p>For source downloads of PHP 8.4.0, Beta 5 please visit the <a href="https://downloads.php.net/~calvinb">download page</a>.</p><p>Please carefully test this version and report any issues found in the <a href="https://github.com/php/php-src/issues">bug reporting system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.4.0beta5/NEWS">NEWS</a> file or the <a href="https://github.com/php/php-src/blob/php-8.4.0beta5/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be RC 1, planned for 26 September 2024.</p><p>The signatures for the release can be found in <a href="https://gist.github.com/NattyNarwhal/2dc0c8a3f7bf63ec5143b4bf703ee626">the manifest</a> or on <a href="https://qa.php.net/">the QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></article><article class="newsentry"><header class="title"><time datetime="2024-08-29T21:40:58+00:00">29 Aug 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.3.11. This is a bug fix release.</p><p>All PHP 8.3 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.3.11 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.3.11">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2024-08-29T18:15:12+00:00">29 Aug 2024</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the release of PHP 8.4.0, Beta 4. This is the second beta release, continuing the PHP 8.4 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php84">PHP Wiki</a>.</p><p>For source downloads of PHP 8.4.0, Beta 4 please visit the <a href="https://downloads.php.net/~saki">download page</a>.</p><p>Please carefully test this version and report any issues found in the <a href="https://github.com/php/php-src/issues">bug reporting system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.4.0beta4/NEWS">NEWS</a> file or the <a href="https://github.com/php/php-src/blob/php-8.4.0beta4/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be Beta 5, planned for 12 September 2024.</p><p>The signatures for the release can be found in <a href="https://gist.github.com/SakiTakamachi/7132a67e0cdc1e792fa1e88f1726d5cc">the manifest</a> or on <a href="https://qa.php.net/">the QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></article><article class="newsentry"><header class="title"><time datetime="2024-08-29T15:58:02+00:00">29 Aug 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.23. This is a bug fix release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.23 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.23">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2024-08-15T13:45:25+00:00">15 Aug 2024</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the release of PHP 8.4.0, Beta 3. This is the first beta release, continuing the PHP 8.4 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php84">PHP Wiki</a>.</p><p>For source downloads of PHP 8.4.0, Beta 3 please visit the <a href="https://downloads.php.net/~calvinb">download page</a>.</p><p>Please carefully test this version and report any issues found in the <a href="https://github.com/php/php-src/issues">bug reporting system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.4.0beta3/NEWS">NEWS</a> file or the <a href="https://github.com/php/php-src/blob/php-8.4.0beta3/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be Beta 4, planned for 29 August 2024.</p><p>The signatures for the release can be found in <a href="https://gist.github.com/NattyNarwhal/fdd2de9d3b165143d376679258811c15">the manifest</a> or on <a href="https://qa.php.net/">the QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></article><article class="newsentry"><header class="title"><time datetime="2024-08-01T23:21:43+00:00">01 Aug 2024</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the second testing release of PHP 8.4.0, Alpha 4. This continues the PHP 8.4 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php84">PHP Wiki</a>.</p><p>For source downloads of PHP 8.4.0 Alpha 4 please visit the <a href="https://downloads.php.net/~saki/">download page</a>.</p><p>Please carefully test this version and report any issues found in the <a href="https://github.com/php/php-src/issues">bug reporting system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.4.0alpha4/NEWS">NEWS</a> file, or the <a href="https://github.com/php/php-src/blob/php-8.4.0alpha4/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be Beta 1, planned for 15 Aug 2024.</p><p>The signatures for the release can be found in <a href="https://gist.github.com/SakiTakamachi/6ef16057e96947aa030408db244718a7">the manifest</a> or on <a href="https://qa.php.net/">the QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></article><article class="newsentry"><header class="title"><time datetime="2024-08-01T16:12:06+00:00">01 Aug 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.22. This is a bug fix release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.22 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.22">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2024-08-01T13:28:53+00:00">01 Aug 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.3.10. This is a bug fix release.</p><p>All PHP 8.3 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.3.10 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.3.10">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2024-07-18T13:30:46+00:00">18 Jul 2024</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the second testing release of PHP 8.4.0, Alpha 2. This continues the PHP 8.4 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php84">PHP Wiki</a>.</p><p>For source downloads of PHP 8.4.0 Alpha 2 please visit the <a href="https://downloads.php.net/~calvinb/">download page</a>.</p><p>Please carefully test this version and report any issues found in the <a href="https://github.com/php/php-src/issues">bug reporting system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.4.0alpha2/NEWS">NEWS</a> file, or the <a href="https://github.com/php/php-src/blob/php-8.4.0alpha2/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be Alpha 3, planned for 1 Aug 2024.</p><p>The signatures for the release can be found in <a href="https://gist.github.com/NattyNarwhal/74b55b8fcc6411ff8db05f87a6f41864">the manifest</a> or on <a href="https://qa.php.net/">the QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></article><article class="newsentry"><header class="title"><time datetime="2024-07-05T13:22:12+00:00">05 Jul 2024</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the first testing release of PHP 8.4.0, Alpha 1. This starts the PHP 8.4 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php84">PHP Wiki</a>.</p><p>For source downloads of PHP 8.4.0 Alpha 1 please visit the <a href="https://downloads.php.net/~saki/">download page</a>.</p><p>Please carefully test this version and report any issues found using <a href="https://github.com/php/php-src/issues">the bug tracking system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.4.0alpha1/NEWS">NEWS</a> file, or the <a href="https://github.com/php/php-src/blob/php-8.4.0alpha1/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be Alpha 2, planned for 18 Jul 2024.</p><p>The signatures for the release can be found in the <a href="https://gist.github.com/SakiTakamachi/d3e32b780590319bee72d8402593a3ca">manifest</a> or on the <a href="https://qa.php.net/">QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></article><article class="newsentry"><header class="title"><time datetime="2024-07-04T22:59:58+00:00">04 Jul 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.3.9. This is a bug fix release.</p><p>All PHP 8.3 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.3.9 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.3.9">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2024-07-04T14:43:24+00:00">04 Jul 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.21. This is a bug fix release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.21 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.21">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2024-06-06T14:56:47+00:00">06 Jun 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.20. This is a security release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.20 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.20">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2024-06-06T14:42:14+00:00">06 Jun 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.3.8. This is a security release.</p><p>All PHP 8.3 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.3.8 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.3.8">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2024-06-06T14:12:51+00:00">06 Jun 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.1.29. This is a security release.</p><p>All PHP 8.1 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.1.29 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.1.29">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2024-05-09T14:40:06+00:00">09 May 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.3.7. This is a bug fix release.</p><p>All PHP 8.3 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.3.7 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.3.7">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2024-05-09T13:48:33+00:00">09 May 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.19. This is a bug fix release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.19 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.19">ChangeLog</a>.</p></div></article></div></section><aside class="tips"><div class="inner"><div class="panel"><div class="body"><p>The PHP Foundation is a collective of people and organizations, united in the mission to ensure the long-term prosperity of the PHP language.</p><p><a href="https://thephp.foundation/donate/" class="btn btn-primary">Donate</a></p></div></div><p class="panel"><a href="https://www.php.net/cal.php">User Group Events</a></p><p class="panel"><a href="https://www.php.net/thanks.php">Special Thanks</a></p></div>
</aside></div>]]></description>
      <link>https://www.php.net/index.php#2024-10-24-3</link>
      <guid>https://www.php.net/index.php#2024-10-24-3</guid>
      <pubDate>Thu, 24 Oct 2024 02:00:00 +0200</pubDate>
    </item>
    <item>
      <title><![CDATA[Property hooks in practice - Larry Garfield]]></title>
      <description><![CDATA[<header><p>Submitted by Larry on 22 October 2024 - 11:32pm</p>
</header><div class="node__content clearfix"><div class="clearfix text-formatted field field--name-body field--type-text-with-summary field--label-hidden field__item"><p>Two of the biggest features in the upcoming PHP 8.4 are property hooks and asymmetric visibility (or "aviz" for short). Ilija Tovilo and I worked on them over the course of two years, and they're finally almost here!</p><p>OK, so now what?</p><p>Rather than just reiterate what's in their respective RFCs (there are many blog posts that do that already), today I want to walk through a real-world application I'm working on as a side project, where I just converted a portion of it to use hooks and aviz. Hopefully that will give a better understanding of the practical benefits of these tools, and where there may be a rough edge or two still left.</p><p>One of the primary use cases for hooks is to not use them: They're there in case you need them, so you don't need to make boilerplate getter/setter methods "just in case." However, that's not their only use. They're also really nice when combined with interface properties, and delegation. Let's have a look.</p><p><em>Continue reading this post on <a href="https://peakd.com/hive-168588/@crell/property-hooks-in-practice">PeakD</a></em></p></div><div class="field field--name-blog-topics field--type-entity-reference field--label-hidden field__items"><p><a href="https://www.garfieldtech.com/topics/web-development/php" hreflang="en">PHP</a></p><p><a href="https://www.garfieldtech.com/taxonomy/term/135" hreflang="en">PHP8.4</a></p><p><a href="https://www.garfieldtech.com/taxonomy/term/136" hreflang="en">Property Hooks</a></p></div></div>]]></description>
      <link>https://www.garfieldtech.com/blog/property-hooks-in-practice</link>
      <guid>https://www.garfieldtech.com/blog/property-hooks-in-practice</guid>
      <pubDate>Wed, 23 Oct 2024 06:32:00 +0200</pubDate>
    </item>
    <item>
      <title><![CDATA[In the future using top-level await might be cause a backwards compatibility break in Node - Evert Pot]]></title>
      <description><![CDATA[<p><a href="https://nodejs.org/en/blog/release/v23.0.0">Node 23</a> was released this week, and the hot ticket item probably is the fact that you can now <code class="language-plaintext highlighter-rouge">require()</code> files that use ESM (<code class="language-plaintext highlighter-rouge">import</code>/<code class="language-plaintext highlighter-rouge">export</code>).</p><p>This is helpful because ESM and CommonJS (<code class="language-plaintext highlighter-rouge">require</code>/<code class="language-plaintext highlighter-rouge">module.exports</code>) are kind of different worlds and before this change if you wanted to use a “module” from your CommonJS file, you would need to do something like:</p><div class="language-javascript highlighter-rouge highlight"><pre>const theThing = await import('some/module/file.mjs');
</pre></div><p>This is called a <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/import">dynamic import</a> and it’s extra annoying, because you can’t just put this at the top of your file. It returns a Promise, so you can only import these modules ‘asynchronously’ or in functions. The reason is that you can only <code class="language-plaintext highlighter-rouge">await</code> inside functions in CommonJS files. So this syntax prevents importing a “module” and immediately using it. To use a module in CommonJS, you’ll need some kind of initialization logic.</p><p>Many Javascript packages resort to <a href="https://evertpot.com/universal-commonjs-esm-typescript-packages/">shipping both a ‘CommonJS’ and a ‘ESM’ version of their code</a> to reduce this kind of annoyance, but not everyone does.</p><h2 id="the-node-23-change">The Node 23 change</h2><p>Node 23 makes it possible to load ESM modules transparently via <code class="language-plaintext highlighter-rouge">require()</code>. This means that the above example can be rewritten to:</p><div class="language-javascript highlighter-rouge highlight"><pre>const theThing = require('some/module/file.mjs');
</pre></div><p>The important part here is not the usage of <code class="language-plaintext highlighter-rouge">require</code>, but the absense of <code class="language-plaintext highlighter-rouge">await</code>. This allows ESM modules to be loaded without this kind of initialization logic.</p><p>But there’s a big caveat:</p><p>This <em>only</em> works if the module you loaded in is not using top-level await. “Top level await” means awaiting things outside of (async) functions, which is possible in modules (but not CommonJS).</p><p>If a top-level await <em>was</em> used, a <code class="language-plaintext highlighter-rouge">ERR_REQUIRE_ASYNC_MODULE</code> error will be thrown. But the important thing to note is that this doesn’t just apply to the file you are directly importing/requiring. It also applies to any files loaded by that file, at any level in either your project or any dependency or sub-dependencies.</p><h2 id="using-top-level-await-is-now-a-bc-break">Using top-level await is now a BC break</h2><p>Typically when we think of backwards compatibility breaks that require a major new version in semver, you might think of functions changing, or removing or arguments no longer being supported.</p><p>Before this change in Node, if your project was fully switched to ESM you might not think of placing a top-level <code class="language-plaintext highlighter-rouge">await</code> anywhere in your code as a backwards compatibility break, but if it’s the first <code class="language-plaintext highlighter-rouge">await</code> you might now inadvertently break Node.js users, if they used <code class="language-plaintext highlighter-rouge">require()</code> to bring in your module.</p><p>This means that the first top-level <code class="language-plaintext highlighter-rouge">await</code> in your project (or any of your dependencies) might now constitute a new major version if you follow <a href="https://semver.org/">semver</a>.</p><h3 id="1-tell-your-users-you-dont-support-require">1. Tell your users you don’t support require()</h3><p>You could effectively tell them if they use <code class="language-plaintext highlighter-rouge">require()</code> they’re on their own. Chances are that your users won’t read this and do it anyway, but arguably they should read the readme of a package they bring in.</p><h3 id="2-add-a-dummy-await">2. Add a dummy await</h3><p>Do you think you or your dependencies might use a top-level await in the future, but you don’t yet? You could add this line to your source to reserve the right to do it later:</p><div class="language-javascript highlighter-rouge highlight"><pre>await "Good things come to those that support await"
</pre></div><h3 id="3-explictly-break-commonjs">3. Explictly break CommonJS</h3><p>Packages can provide both CommonJS and ESM support via the <a href="https://nodejs.org/api/packages.html#exports"><code class="language-plaintext highlighter-rouge">exports</code></a> key in <code class="language-plaintext highlighter-rouge">package.json</code>. It could be an option to export a single CommonJS file that just throws an error to warn CommonJS users they shouldn’t use this package.</p><p>Out of these 3 options, I kind of like 2 because if Node.js ever changes behavior and <em>does</em> support loading modules that use top-level await in CommonJS files it will one day just start working.</p><p>Regardless. it does feel important to me that package maintainers that only ship ESM, or ship CommonJS and intend to use this new feature have a strategy, because it’s bound to blow up if not.</p><p>In Bun you can use <a href="https://docs.deno.com/runtime/tutorials/cjs_to_esm/"><code class="language-plaintext highlighter-rouge">import</code> and <code class="language-plaintext highlighter-rouge">require</code></a> in the same file, so there’s fewer trade-offs to make. But if you do use <code class="language-plaintext highlighter-rouge">require()</code> to import a module with top-level await it still has the same issue. There’s just fewer reasons in Bun to even want to do this.</p><p>Deno <a href="https://docs.deno.com/runtime/tutorials/cjs_to_esm/">doesn’t support CommonJS</a> so it doesn’t have that problem.</p><h2 id="does-the-issue-exists-when-importing-commonjs-files-into-modules">Does the issue exists when importing CommonJS files into modules?</h2><p>Importing CommonJS files into modules was always possible via the standard <code class="language-plaintext highlighter-rouge">import</code> syntax, and because CommonJS can’t asynchronously export this problem doesn’t exist there.</p><h2 id="what-should-i-do-as-a-user">What should I do as a user?</h2><p>Most of this article was about the effects for package maintainers, but not every package will do this well so as a user you’re still potentially exposed to this issue.</p><p>In order of preference, consider the following:</p><ol><li>Stop using CommonJS. Start using ESM everywhere. This issue only exists in CommonJS files using ESM, not the reverse. ESM is the future. You’re working with dead-end technology.</li>
<li>Have some testing in place that at the very least loads the entirely of your code-base. If all (top-level, not-dynamic) <code class="language-plaintext highlighter-rouge">requires()</code> are ran/resolved, any changes in depndencies should just blow up your CI environment and application.</li>
<li>Find out if any of your dependencies are ESM-only, and never <code class="language-plaintext highlighter-rouge">require()</code> them. This protects you from issues with direct dependencies. But keep in mind that this can still be an issue in sub-dependencies even if your direct dependencies are CommonJS themselves!</li>
</ol><h2 id="my-opinion">My opinion</h2><p>For the above reasons I don’t think this should land in a stable Node.js version. The intentions are good but it creates yet another avenue of confusion.</p><p>It effectively expands the number of Javascript flavors from 2 to 3:</p><ol><li>CommonJS</li>
<li>ESM</li>
<li>ESM but without top-level await.</li>
</ol><p>If a module uses flavor #3, it’s compatible with flavor #1, but if anywhere in the dependency tree something starts using top-level await, suddenly the entire tree ESM dependency tree cascades from flavor #3 to #2 and breaks compatibilty with flavor #1.</p><p>Given the already confusing landscape (and reputation) of Javascript modules, this feels like a step in the wrong direction, as it adds a feature to CommonJS (which in my opinion is time to freeze), and makes ESM <em>less</em> reliable as a result.</p>]]></description>
      <link>https://evertpot.com/using-top-level-await-is-bc-break/</link>
      <guid>https://evertpot.com/using-top-level-await-is-bc-break/</guid>
      <pubDate>Fri, 18 Oct 2024 03:13:00 +0200</pubDate>
    </item>
    <item>
      <title><![CDATA[Discovering features using HTTP OPTIONS - Evert Pot]]></title>
      <description><![CDATA[<p>Say you have an API, and you want to communicate what sort of things a user can do on a specific endpoint. You can use external description formats like OpenAPI or JSON Schema, but sometimes it’s nice to also dynamically communicate this on the API itself.</p><p><a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/OPTIONS"><code class="language-plaintext highlighter-rouge">OPTIONS</code></a> is the method used for that. You may know this HTTP method from <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS">CORS</a>, but it’s general purpose is for clients to passively find out ‘What can I do here?’.</p><p>All HTTP clients typically support making <code class="language-plaintext highlighter-rouge">OPTIONS</code> request. For example with <code class="language-plaintext highlighter-rouge">fetch()</code>:</p><div class="language-javascript highlighter-rouge highlight"><pre>const response = await fetch(
  'https://example.org',
  {method: 'OPTIONS'}
);
</pre></div><p>A basic <code class="language-plaintext highlighter-rouge">OPTIONS</code> response might might look like this:</p><div class="language-http highlighter-rouge highlight"><pre>HTTP/1.1 204 No Content
Date: Mon, 23 Sep 2024 02:57:38 GMT
Server: KKachel/1.2
Allow: GET, PUT, POST, DELETE, OPTIONS
</pre></div><p>Based on the <a href="https://www.rfc-editor.org/rfc/rfc9110.html#field.allow" title="Allow header"><code class="language-plaintext highlighter-rouge">Allow</code></a> header you can quickly tell which HTTP methods are available at a given endpoint. Many web frameworks emit this automatically and generate the list of methods dynamically per route, so chances are that you get this one for free.</p><p>To find out if your server does, try running the command below (with your URL!):</p><div class="language-plaintext highlighter-rouge highlight"><pre>curl -X OPTIONS http://localhost:3000/some/endpoint/
</pre></div><p>One nice thing you could do with the <code class="language-plaintext highlighter-rouge">Allow</code> header, is that you could also communicate access-control information on a very basic level. For example, you could only include <code class="language-plaintext highlighter-rouge">DELETE</code> and <code class="language-plaintext highlighter-rouge">PUT</code> if a user has write access to a resource.</p><h2 id="accept-and-accept-encoding">Accept and Accept-Encoding</h2><p>There’s server other standard headers for discovery. Here’s an example showing a few at once:</p><div class="language-http highlighter-rouge highlight"><pre>HTTP/1.1 204 No Content
Date: Mon, 23 Sep 2024 02:57:38 GMT
Server: KKachel/1.2
Allow: GET, PUT, POST, DELETE, OPTIONS
Accept: application/vnd.my-company-api+json, application/json, text/html
Accept-Encoding: gzip,brotli,identity
</pre></div><p>You may already be familiar with <a href="https://www.rfc-editor.org/rfc/rfc9110.html#name-accept" title="Accept header"><code class="language-plaintext highlighter-rouge">Accept</code></a> and <a href="https://www.rfc-editor.org/rfc/rfc9110.html#name-accept-encoding" title="Accept-Encoding header"><code class="language-plaintext highlighter-rouge">Accept-Encoding</code></a> from HTTP requests, but they can also appear in responses. <code class="language-plaintext highlighter-rouge">Accept</code> in a response lets you tell the client which kind of mimetypes are available at an endpoint. I like adding <code class="language-plaintext highlighter-rouge">text/html</code> to every JSON api endpoint and making sure that API urls can be opened in browsers and shared between devs for easy debugging.</p><p>The <code class="language-plaintext highlighter-rouge">Accept-Encoding</code> lets a client know in this case that they can compress their request bodies with either <code class="language-plaintext highlighter-rouge">gzip</code> or <code class="language-plaintext highlighter-rouge">brotli</code> (<code class="language-plaintext highlighter-rouge">identity</code> means no compression).</p><h2 id="patching-posting-and-querying">Patching, posting and querying</h2><p>3 other headers that can be used are <a href="https://www.rfc-editor.org/rfc/rfc5789#section-3.1" title="Accept-Patch header"><code class="language-plaintext highlighter-rouge">Accept-Patch</code></a>, <a href="https://www.w3.org/TR/ldp/#header-accept-post" title="Accept-Post header"><code class="language-plaintext highlighter-rouge">Accept-Post</code></a> and <a href="https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-safe-method-w-body-05#name-the-accept-query-header-fie" title="Accept-Query header"><code class="language-plaintext highlighter-rouge">Accept-Query</code></a>. These three headers are used to tell a client what content-types are available for the <a href="https://www.rfc-editor.org/rfc/rfc5789#section-2" title="PATCH method"><code class="language-plaintext highlighter-rouge">PATCH</code></a>, <a href="https://www.rfc-editor.org/rfc/rfc9110.html#name-post" title="POST method"><code class="language-plaintext highlighter-rouge">POST</code></a> and <a href="https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-safe-method-w-body-05#name-query" title="QUERY method"><code class="language-plaintext highlighter-rouge">QUERY</code></a> http methods respectively.</p><p>For all of these headers, their values effectively dictate what valid values are for the <code class="language-plaintext highlighter-rouge">Content-Type</code> header when making the request.</p><div class="language-http highlighter-rouge highlight"><pre>HTTP/1.1 204 No Content
Date: Mon, 23 Sep 2024 02:57:38 GMT
Server: KKachel/1.2
Allow: OPTIONS, QUERY, POST, PATCH
Accept-Patch: application/json-patch+json, application/merge-patch+json
Accept-Query: application/graphql
Accept-Post: multipart/form-data, application/vnd.custom.rpc+json
</pre></div><p>In the above response, the server indicates it supports both <a href="https://datatracker.ietf.org/doc/html/rfc6902" title="JSON Patch">JSON Patch</a> and <a href="https://datatracker.ietf.org/doc/html/rfc7386" title="JSON Merge Patch">JSON Merge Patch</a> content-types in <code class="language-plaintext highlighter-rouge">PATCH</code> requests. It also suggests that GraphQL can be used via the <code class="language-plaintext highlighter-rouge">QUERY</code> method, and for <code class="language-plaintext highlighter-rouge">POST</code> it supports both standard file uploads and some custom JSON-based format.</p><p>Typically you wouldn’t find all of these at the same endpoint, but I wanted to show a few examples together.</p><h2 id="wheres-put">Where’s PUT?</h2><p>Oddly, there’s no specific header for <code class="language-plaintext highlighter-rouge">PUT</code> requests. Arguably you could say that <code class="language-plaintext highlighter-rouge">GET</code> and <code class="language-plaintext highlighter-rouge">PUT</code> are symmetrical, so perhaps the <code class="language-plaintext highlighter-rouge">Accept</code> header kind of extends to both. But the spec is not clear on this.</p><p>I think the actual reality is that <code class="language-plaintext highlighter-rouge">Accept-Patch</code> was the first header in this category that really clearly defined this as a means of feature discovery on <code class="language-plaintext highlighter-rouge">OPTIONS</code>. <code class="language-plaintext highlighter-rouge">Accept-Post</code> and <code class="language-plaintext highlighter-rouge">Accept-Query</code> followed suit. I think <code class="language-plaintext highlighter-rouge">Accept-Patch</code> in <code class="language-plaintext highlighter-rouge">OPTIONS</code> was modelled after in-the-wild usage of <code class="language-plaintext highlighter-rouge">Accept</code> in <code class="language-plaintext highlighter-rouge">OPTIONS</code>, even though the HTTP specific doesn’t super clearly define this.</p><p>If I’m wrong with my interpretation here, I would love to know!</p><p><small><em>Aside: If you’re wondering about <code class="language-plaintext highlighter-rouge">DELETE</code>, <code class="language-plaintext highlighter-rouge">DELETE</code> should never have a body, so all a user would need to know is <em>can</em> they delete, which you can see in the <code class="language-plaintext highlighter-rouge">Allow</code> header. If this is new to you to, <a href="https://www.rfc-editor.org/rfc/rfc8631.html#section-4.2" title="service-desc link relationship">read my other article</a> about <code class="language-plaintext highlighter-rouge">GET</code> request bodies. Most of the information there is applicable to <code class="language-plaintext highlighter-rouge">DELETE</code> as well.</em></small></p><p>The <code class="language-plaintext highlighter-rouge">OPTIONS</code> response is also a great place to tell users where to find additional documentation. In the below example, I included both a machine-readable link to a documentation site, a link to an OpenAPI definition, and a message intended for humans in the response body:</p><div class="language-http highlighter-rouge highlight"><pre>HTTP/1.1 200 OK
Date: Mon, 23 Sep 2024 04:45:38 GMT
Allow: GET, QUERY, OPTIONS
Link: &lt;https://docs.example.org/api/some-endpoint&gt;; rel="service-doc"
Link: &lt;https://api.example.org/openapi.yml&gt;; rel="service-desc" type="application/openapi+yaml"
Content-Type: text/plain
Hey there!
Thanks for checking out this API. You can find the docs for this
specific endpoint at: https://docs.example.org/api/some-endpoint
Cheers,
The dev team
</pre></div><p>I recommend keeping the response body as mostly informal and minimal any real information should probably just live on its own URL and be linked to.</p><p>I used the <a href="https://www.rfc-editor.org/rfc/rfc8631.html#section-4.1" title="service-doc link relationship"><code class="language-plaintext highlighter-rouge">service-doc</code></a> and <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types" title="Mime types"><code class="language-plaintext highlighter-rouge">service-desc</code></a> link relationships here, but you can of course use any of the <a href="https://www.iana.org/assignments/link-relations/link-relations.xhtml" title="IANA link relations registry">IANA link relationship types</a> here or a custom one. Also see the <a href="https://datatracker.ietf.org/doc/html/rfc8288" title="Web Linking">Web linking</a> spec for more info.</p><h2 id="obscure-uses">Obscure uses</h2><h3 id="webdav-usage">WebDAV usage</h3><p>WebDAV, CalDAV and CardDAV also use OPTIONS for feature discovery. For example:</p><div class="language-http highlighter-rouge highlight"><pre>HTTP/1.1 204 No Content
Date: Mon, 23 Sep 2024 05:01:50 GMT
Allow: GET, PROPFIND, ACL, PROPPATCH, MKCOL, LOCK, UNLOCK
DAV: 1, 2, 3, access-control, addressbook, calendar-access
</pre></div><h3 id="the-server-wide-asterisk-request">The server-wide asterisk request</h3><p>Normally HTTP requests are made to a path on the server, and the first line looks a bit like the following in HTTP/1.1:</p><div class="language-http highlighter-rouge highlight"><pre>GET /path HTTP/1.1
</pre></div><p>But, there are a few other “request line” formats that are rarely used. One of them lets you discover features available on an entire server, using the asterisk:</p><div class="language-http highlighter-rouge highlight"><pre>OPTIONS * HTTP/1.1
</pre></div><p>The asterisk here is not a path. Normally asterisks aren’t even allowed in URIs. Many HTTP clients (including <code class="language-plaintext highlighter-rouge">fetch()</code>) don’t even support this request.</p><p>Classic webservers like Apache and Nginx should support this. To try it out, use CURL</p><div class="language-sh highlighter-rouge highlight"><pre>curl -vX OPTIONS --request-target '*' http://example.org
</pre></div><h2 id="final-notes">Final notes</h2><p>If you have a reason to allow clients to discover features on an endpoint, consider using <code class="language-plaintext highlighter-rouge">OPTIONS</code> instead of a proprietary approach! As you can see in many of these examples, it’s especially useful if you use <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types" title="Mime types">mimetypes</a> well.</p><p>If you have questions, other novel uses of <code class="language-plaintext highlighter-rouge">OPTIONS</code> or other ideas around feature discovery, you can respond via:</p>]]></description>
      <link>https://evertpot.com/discovering-features-with-http-options/</link>
      <guid>https://evertpot.com/discovering-features-with-http-options/</guid>
      <pubDate>Wed, 16 Oct 2024 15:44:00 +0200</pubDate>
    </item>
    <item>
      <title><![CDATA[PHP 8.4.0 RC2 available for testing - PHP: Hypertext Preprocessor]]></title>
      <description><![CDATA[<div id="intro" class="clearfix container hero"><img class="hero-logo" src="https://www.php.net/images/logos/php-logo-white.svg" alt="php" width="240" height="120" /><p class="hero-text">A <strong>popular general-purpose scripting language</strong> that is especially suited to web development.<br />Fast, flexible and pragmatic, PHP powers everything from your blog to the most popular websites in the world.</p><p><a href="https://www.php.net/releases/8.3/index.php" class="hero-btn hero-btn-primary">What's new in 8.3</a> <a href="https://www.php.net/downloads.php" class="hero-btn hero-btn-secondary">Download</a></p><ul class="hero-versions"><li class="hero-version"><a class="hero-version-link" href="https://www.php.net/downloads.php#v8.3.12">8.3.12</a> · <a class="notes" href="https://www.php.net/ChangeLog-8.php#8.3.12">Changelog</a> · <a class="notes" href="https://www.php.net/migration83">Upgrading</a></li>
<li class="hero-version"><a class="hero-version-link" href="https://www.php.net/downloads.php#v8.2.24">8.2.24</a> · <a class="notes" href="https://www.php.net/ChangeLog-8.php#8.2.24">Changelog</a> · <a class="notes" href="https://www.php.net/migration82">Upgrading</a></li>
<li class="hero-version"><a class="hero-version-link" href="https://www.php.net/downloads.php#v8.1.30">8.1.30</a> · <a class="notes" href="https://www.php.net/ChangeLog-8.php#8.1.30">Changelog</a> · <a class="notes" href="https://www.php.net/migration81">Upgrading</a></li>
</ul></div><div id="layout" class="clearfix"><section id="layout-content"><div class="home-content"><article class="newsentry"><header class="title"><time datetime="2024-10-10T14:04:23+00:00">10 Oct 2024</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the release of PHP 8.4.0, RC2. This is the second release candidate, continuing the PHP 8.4 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php84">PHP Wiki</a>.</p><p>For source downloads of PHP 8.4.0, RC2 please visit the <a href="https://downloads.php.net/~calvinb">download page</a>.</p><p>Please carefully test this version and report any issues found in the <a href="https://github.com/php/php-src/issues">bug reporting system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.4.0RC2/NEWS">NEWS</a> file or the <a href="https://github.com/php/php-src/blob/php-8.4.0RC2/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be RC 3, planned for 24 October 2024.</p><p>The signatures for the release can be found in <a href="https://gist.github.com/NattyNarwhal/ea2bb82ce1e3fb67f385b2d6e2e085dc">the manifest</a> or on <a href="https://qa.php.net/">the QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></article><article class="newsentry"><header class="title"><time datetime="2024-09-26T19:56:50+00:00">26 Sep 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.1.30. This is a security release.</p><p>All PHP 8.1 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.1.30 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.1.30">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2024-09-26T19:25:27+00:00">26 Sep 2024</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the release of PHP 8.4.0, RC 1. This is the first release candidate, continuing the PHP 8.4 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php84">PHP Wiki</a>.</p><p>For source downloads of PHP 8.4.0, RC 1 please visit the <a href="https://downloads.php.net/~saki">download page</a>.</p><p>Please carefully test this version and report any issues found in the <a href="https://github.com/php/php-src/issues">bug reporting system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.4.0RC1/NEWS">NEWS</a> file or the <a href="https://github.com/php/php-src/blob/php-8.4.0RC1/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be RC 2, planned for 10 October 2024.</p><p>The signatures for the release can be found in <a href="https://gist.github.com/SakiTakamachi/198dac0514f8cba37ed3506526cd1fb2">the manifest</a> or on <a href="https://qa.php.net/">the QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></article><article class="newsentry"><header class="title"><time datetime="2024-09-26T16:25:23+00:00">26 Sep 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.24. This is a security release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.24 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.24">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2024-09-26T13:31:15+00:00">26 Sep 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.3.12. This is a security release.</p><p>All PHP 8.3 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.3.12 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.3.12">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2024-09-12T14:14:49+00:00">12 Sep 2024</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the release of PHP 8.4.0, Beta 5. This is the third beta release, continuing the PHP 8.4 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php84">PHP Wiki</a>.</p><p>For source downloads of PHP 8.4.0, Beta 5 please visit the <a href="https://downloads.php.net/~calvinb">download page</a>.</p><p>Please carefully test this version and report any issues found in the <a href="https://github.com/php/php-src/issues">bug reporting system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.4.0beta5/NEWS">NEWS</a> file or the <a href="https://github.com/php/php-src/blob/php-8.4.0beta5/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be RC 1, planned for 26 September 2024.</p><p>The signatures for the release can be found in <a href="https://gist.github.com/NattyNarwhal/2dc0c8a3f7bf63ec5143b4bf703ee626">the manifest</a> or on <a href="https://qa.php.net/">the QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></article><article class="newsentry"><header class="title"><time datetime="2024-08-29T21:40:58+00:00">29 Aug 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.3.11. This is a bug fix release.</p><p>All PHP 8.3 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.3.11 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.3.11">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2024-08-29T18:15:12+00:00">29 Aug 2024</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the release of PHP 8.4.0, Beta 4. This is the second beta release, continuing the PHP 8.4 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php84">PHP Wiki</a>.</p><p>For source downloads of PHP 8.4.0, Beta 4 please visit the <a href="https://downloads.php.net/~saki">download page</a>.</p><p>Please carefully test this version and report any issues found in the <a href="https://github.com/php/php-src/issues">bug reporting system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.4.0beta4/NEWS">NEWS</a> file or the <a href="https://github.com/php/php-src/blob/php-8.4.0beta4/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be Beta 5, planned for 12 September 2024.</p><p>The signatures for the release can be found in <a href="https://gist.github.com/SakiTakamachi/7132a67e0cdc1e792fa1e88f1726d5cc">the manifest</a> or on <a href="https://qa.php.net/">the QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></article><article class="newsentry"><header class="title"><time datetime="2024-08-29T15:58:02+00:00">29 Aug 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.23. This is a bug fix release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.23 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.23">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2024-08-15T13:45:25+00:00">15 Aug 2024</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the release of PHP 8.4.0, Beta 3. This is the first beta release, continuing the PHP 8.4 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php84">PHP Wiki</a>.</p><p>For source downloads of PHP 8.4.0, Beta 3 please visit the <a href="https://downloads.php.net/~calvinb">download page</a>.</p><p>Please carefully test this version and report any issues found in the <a href="https://github.com/php/php-src/issues">bug reporting system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.4.0beta3/NEWS">NEWS</a> file or the <a href="https://github.com/php/php-src/blob/php-8.4.0beta3/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be Beta 4, planned for 29 August 2024.</p><p>The signatures for the release can be found in <a href="https://gist.github.com/NattyNarwhal/fdd2de9d3b165143d376679258811c15">the manifest</a> or on <a href="https://qa.php.net/">the QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></article><article class="newsentry"><header class="title"><time datetime="2024-08-01T23:21:43+00:00">01 Aug 2024</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the second testing release of PHP 8.4.0, Alpha 4. This continues the PHP 8.4 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php84">PHP Wiki</a>.</p><p>For source downloads of PHP 8.4.0 Alpha 4 please visit the <a href="https://downloads.php.net/~saki/">download page</a>.</p><p>Please carefully test this version and report any issues found in the <a href="https://github.com/php/php-src/issues">bug reporting system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.4.0alpha4/NEWS">NEWS</a> file, or the <a href="https://github.com/php/php-src/blob/php-8.4.0alpha4/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be Beta 1, planned for 15 Aug 2024.</p><p>The signatures for the release can be found in <a href="https://gist.github.com/SakiTakamachi/6ef16057e96947aa030408db244718a7">the manifest</a> or on <a href="https://qa.php.net/">the QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></article><article class="newsentry"><header class="title"><time datetime="2024-08-01T16:12:06+00:00">01 Aug 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.22. This is a bug fix release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.22 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.22">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2024-08-01T13:28:53+00:00">01 Aug 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.3.10. This is a bug fix release.</p><p>All PHP 8.3 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.3.10 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.3.10">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2024-07-18T13:30:46+00:00">18 Jul 2024</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the second testing release of PHP 8.4.0, Alpha 2. This continues the PHP 8.4 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php84">PHP Wiki</a>.</p><p>For source downloads of PHP 8.4.0 Alpha 2 please visit the <a href="https://downloads.php.net/~calvinb/">download page</a>.</p><p>Please carefully test this version and report any issues found in the <a href="https://github.com/php/php-src/issues">bug reporting system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.4.0alpha2/NEWS">NEWS</a> file, or the <a href="https://github.com/php/php-src/blob/php-8.4.0alpha2/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be Alpha 3, planned for 1 Aug 2024.</p><p>The signatures for the release can be found in <a href="https://gist.github.com/NattyNarwhal/74b55b8fcc6411ff8db05f87a6f41864">the manifest</a> or on <a href="https://qa.php.net/">the QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></article><article class="newsentry"><header class="title"><time datetime="2024-07-05T13:22:12+00:00">05 Jul 2024</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the first testing release of PHP 8.4.0, Alpha 1. This starts the PHP 8.4 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php84">PHP Wiki</a>.</p><p>For source downloads of PHP 8.4.0 Alpha 1 please visit the <a href="https://downloads.php.net/~saki/">download page</a>.</p><p>Please carefully test this version and report any issues found using <a href="https://github.com/php/php-src/issues">the bug tracking system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.4.0alpha1/NEWS">NEWS</a> file, or the <a href="https://github.com/php/php-src/blob/php-8.4.0alpha1/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be Alpha 2, planned for 18 Jul 2024.</p><p>The signatures for the release can be found in the <a href="https://gist.github.com/SakiTakamachi/d3e32b780590319bee72d8402593a3ca">manifest</a> or on the <a href="https://qa.php.net/">QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></article><article class="newsentry"><header class="title"><time datetime="2024-07-04T22:59:58+00:00">04 Jul 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.3.9. This is a bug fix release.</p><p>All PHP 8.3 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.3.9 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.3.9">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2024-07-04T14:43:24+00:00">04 Jul 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.21. This is a bug fix release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.21 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.21">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2024-06-06T14:56:47+00:00">06 Jun 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.20. This is a security release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.20 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.20">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2024-06-06T14:42:14+00:00">06 Jun 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.3.8. This is a security release.</p><p>All PHP 8.3 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.3.8 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.3.8">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2024-06-06T14:12:51+00:00">06 Jun 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.1.29. This is a security release.</p><p>All PHP 8.1 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.1.29 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.1.29">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2024-05-09T14:40:06+00:00">09 May 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.3.7. This is a bug fix release.</p><p>All PHP 8.3 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.3.7 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.3.7">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2024-05-09T13:48:33+00:00">09 May 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.19. This is a bug fix release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.19 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.19">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2024-04-24T18:40:29+00:00">24 Apr 2024</time>
</header><div class="newscontent"><p>EDIT 2024-04-25: Clarified when a PHP application is vulnerable to this bug.</p><p>Recently, a bug in <strong>glibc</strong> version 2.39 and older (<a href="https://nvd.nist.gov/vuln/detail/CVE-2024-2961">CVE-2024-2961</a>) was uncovered where a buffer overflow in character set conversions <strong>to</strong> the ISO-2022-CN-EXT character set can result in remote code execution.</p><p>This specific buffer overflow in glibc is exploitable through PHP, which exposes the iconv functionality of glibc to do character set conversions via the <a href="https://www.php.net/manual/en/function.iconv.php">iconv extension</a>. Although the bug is exploitable in the context of the PHP Engine, the bug is not in PHP. It is also not directly exploitable remotely.</p><p>The bug is exploitable, <strong>if and only if</strong>, the PHP application calls iconv <a href="https://www.php.net/manual/en/ref.iconv.php">functions</a> or <a href="https://www.php.net/manual/en/filters.convert.php#filters.convert.iconv">filters</a> with user-supplied character sets.</p><p>Applications are <strong>not</strong> vulnerable if:</p><ul><li>Glibc security updates from the distribution have been installed.</li>
<li>Or the iconv extension is not loaded.</li>
<li>Or the vulnerable character set has been removed from gconv-modules-extra.conf.</li>
<li>Or the application passes only specifically allowed character sets to iconv.</li>
</ul><p>Moreover, when using a user-supplied character set, it is good practice for applications to accept only specific charsets that have been explicitly allowed by the application. One example of how this can be done is by using an allow-list and the <a href="https://www.php.net/manual/en/function.array-search"><code>array_search()</code></a> function to check the encoding before passing it to iconv. For example: <code>array_search($charset, $allowed_list, true)</code></p><p>There are numerous reports online with titles like "Mitigating the iconv Vulnerability for PHP (CVE-2024-2961)" or "PHP Under Attack". These titles are misleading as this is <strong>not</strong> a bug in PHP itself.</p><p>If your PHP application is vulnerable, we first recommend to check if your Linux distribution has already published patched variants of glibc. <a href="https://security-tracker.debian.org/tracker/CVE-2024-2961">Debian</a>, CentOS, and others, have already done so, and please upgrade as soon as possible.</p><p>Once an update is available in glibc, updating that package on your Linux machine will be enough to alleviate the issue. You do not need to update PHP, as glibc is a dynamically linked library.</p><p>If your Linux distribution has not published a patched version of glibc, there is no fix for this issue. However, there exists a workaround described in <a href="https://rockylinux.org/news/glibc-vulnerability-april-2024/">GLIBC Vulnerability on Servers Serving PHP</a> which explains a way on how to remove the problematic character set from glibc. Perform this procedure for every gconv-modules-extra.conf file that is available on your system.</p><p>PHP users on Windows are not affected.</p><p>Therefore, a new version of PHP will not be released for this vulnerability.</p></div></article><article class="newsentry"><header class="title"><time datetime="2024-04-12T15:42:40+00:00">12 Apr 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.1.28. This is a security release.</p><p>All PHP 8.1 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.1.28 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.1.28">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2024-04-11T14:34:04+00:00">11 Apr 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.3.6. This is a security release.</p><p>All PHP 8.3 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.3.6 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.3.6">ChangeLog</a>.</p></div></article></div></section><aside class="tips"><div class="inner"><div class="panel"><div class="body"><p>The PHP Foundation is a collective of people and organizations, united in the mission to ensure the long-term prosperity of the PHP language.</p><p><a href="https://thephp.foundation/donate/" class="btn btn-primary">Donate</a></p></div></div><p class="panel"><a href="https://www.php.net/cal.php">User Group Events</a></p><p class="panel"><a href="https://www.php.net/thanks.php">Special Thanks</a></p></div>
</aside></div>]]></description>
      <link>https://www.php.net/index.php#2024-10-10-1</link>
      <guid>https://www.php.net/index.php#2024-10-10-1</guid>
      <pubDate>Thu, 10 Oct 2024 02:00:00 +0200</pubDate>
    </item>
    <item>
      <title><![CDATA[Varnish Workspace Error - Brian Moon]]></title>
      <description><![CDATA[<header class="article-header">
<p>Mon, Oct 7, 2024 12:21 PM</p>
</header><section class="article-body"><p>We had been having an issue with losing cookies in Varnish. Because of how Varnish works, the way to work around cookies is to store them in headers inbetween states of the request process. We were finally able to get some data out of varnishlog that looked like this.</p><pre>- ReqHeader DN-Varnish-Offer-Group: <br />- LostHeader DN-Varnish-Offer-Sort: price <br />- Error out of workspace (req) <br />- LostHeader DN-Varnish-Sbtab-Sorts: <br />- Error out of workspace (req) <br />- LostHeader DN-Varnish-Use-View: <br />- Error out of workspace (req) <br />- LostHeader DN-Varnish-Ux-Variant: classic_site <br />- Error out of workspace (req)</pre><p>When you first read these errors, you will likely find the settings <code>workspace_client</code> and <code>workspace_backend</code>. Those seem like very logical settings to tweak. However, no matter how big we set them nothing helped. We graph stats coming out of Varnish using the prometheus exporter. We found the metric <code>varnish_main_ws_backend_overflow</code>. That made us believe even more that this was a <code>workspace_backend</code> limit we were hitting. It turns out, there is more to the workspace settings than just this. I read through <a href="https://github.com/mattiasgeniar/varnish-4.0-configuration-templates/issues/37">an old issue on Github</a> and found some folks trying to set other settings related to header size and header limits. In the end, that was our issue. We increased these settings and our overflows disappeared. </p><pre>http_req_hdr_len = 64k (default is 8k)<br />http_req_size = 128k (default is 32k)<br />http_max_hdr=256 (default is 64)</pre><p>Hopefully this will help someone else that runs up against this.</p></section><footer class="article-footer"><p><a href="https://brian.moonspot.net/varnish-out-of-workspace-req#comments">Comments (0)</a></p>
<p><a href="https://brian.moonspot.net/varnish-out-of-workspace-req">Permalink</a></p>
</footer>]]></description>
      <link>https://brian.moonspot.net/varnish-out-of-workspace-req</link>
      <guid>https://brian.moonspot.net/varnish-out-of-workspace-req</guid>
      <pubDate>Mon, 07 Oct 2024 19:21:00 +0200</pubDate>
    </item>
    <item>
      <title><![CDATA[New Structured Fields RFC out, and so is my Javascript package - Evert Pot]]></title>
      <description><![CDATA[<p>A new RFC was released for Structured Fields: <a href="https://www.rfc-editor.org/rfc/rfc9651.html" title="Structured Field Values for HTTP">RFC9651</a>.</p><h2 id="what-is-it">What is it?</h2><p>HTTP headers have been a bit of a free-for all in terms of how complex values are encoded, with many headers requiring their own mini-parser.</p><p>A while back an effort was started to fix this for headers going forward, named ‘Structured Fields’. They’re called Fields and not ‘Headers’ because HTTP has both Headers and Trailers!</p><p>Structured fields let you encode things like lists, dictionaries, strings, numbers, booleans and binary data. The <a href="https://www.rfc-editor.org/rfc/rfc8941.html" title="Structured Field Values for HTTP old spec">original RFC</a> from 2021 is pretty successful and although many existing headers can’t be retrofitted to this format, a lot of new standards are taking advantage.</p><p>Some examples:</p><div class="language-plaintext highlighter-rouge highlight"><pre># Parsed an ASCII string
Header: "foo"
# A simple string, called a 'Token' in the spec
Header: foo
# Parsed as number
Header: 5
Header: -10
Header: 5.01415
# Parsed into boolean
Header: ?1
Header: ?0
# Binaries are base64 encoded
Header: :RE0gbWUgZm9yIGEgZnJlZSBjb29raWU=:
# Items can have parameters
Header: "Hello world"; a="5"
# A simple list
Header: 5, "foo", bar, ?1
# Each element can have parameters
Header: sometoken; param1; param2=hi, 42
# A list can also contain lists itself. These are called 'inner lists' and
# use parenthesis
Header: sometoken, (innerlistitem1 innerlistitem2), (anotherlist)
# A simple dictionary
Header: fn="evert", ln="pot", coffee=?1
# Each item may have parameters too
Header: foo=123; q=1, bar=123, q=0.5
# A dictionary value may be an inner list again
Header: foo=(1 2 3)
</pre></div><p>The new RFC published last week adds 2 new data types: Dates and ‘Display strings’, which is a Unicode serialization that fits in the HTTP header (and trailer) format.</p><div class="language-plaintext highlighter-rouge highlight"><pre># Parsed into a Date object
Header: @1686634251
# A Unicode string, called a 'Display String' in the spec. They use
# percent encoding, but encode a different set of characters than
# URLs.
Header %"Frysl%C3%A2n"
</pre></div><h2 id="why-should-you-care">Why should you care?</h2><p>If you encounter these headers in the wild, it’s a really good idea to use a standard parser. One of the reasons is that with using structured-fields, there’s a built-in extension mechanism. You’ll want to make sure that when a new parameter appears your application doesn’t suddenly break.</p><p>You may also want to define and use your own HTTP headers. The structured fields format is a very good ‘default choice’ that removes decisions such as ‘How should I encode a key value object’ or ‘how do I encode a UTF-8 string’.</p><p>With parsers popping up for every language, you don’t have to worry about writing your own one-off formats.</p><h2 id="javascript-package">Javascript package</h2><p>I’m the maintainer of a Javascript library for Structured Fields, called <a href="https://github.com/badgateway/structured-headers" title="Structured Fields parser/serializer for Javascript and Typescript">“structured headers”</a>, which I’ve also updated for this new RFC. I wish I picked the name “structured-fields”, but I picked the name before the original standard changed it’s name.</p><p>I’ve just released v2 of this library supporting these new types, and also added ES Modules support.</p><p>Reply to one of these:</p><ul><li><a href="https://indieweb.social/@evert/113247162498865971" title="Mastodon post">Mastodon post</a></li>
<li><a href="https://bsky.app/profile/evertp.bsky.social/post/3l5nvxuyfv32m" title="Bluesky post">Bluesky post</a></li>
</ul>]]></description>
      <link>https://evertpot.com/structured-fields-javascript-v2/</link>
      <guid>https://evertpot.com/structured-fields-javascript-v2/</guid>
      <pubDate>Thu, 03 Oct 2024 17:56:00 +0200</pubDate>
    </item>
    <item>
      <title><![CDATA[Hello World, meet Kian - Evert Pot]]></title>
      <description><![CDATA[<main><p><a href="https://evertpot.com/subscribe">subscribe</a></p>
<article class="h-entry"><div class="e-content"><p>One week ago on September 24th my son Kian was born, after a 5 year fertility journey with my wife Roxy. Roxy and Kian are well and I’m really excited for everything that comes next!</p><p><img src="https://evertpot.com/assets/posts/kian.jpg" class="fill-width" title="Evert holding his son Kian at the day of his birth" alt="image" /></p></div></article></main><footer>Written by <a href="https://evertpot.com/">Evert Pot</a>. Find me on <a href="https://github.com/evert">Github</a> or <a rel="me" href="https://indieweb.social/@evert">Mastodon</a>.</footer>]]></description>
      <link>https://evertpot.com/hello-world-kian/</link>
      <guid>https://evertpot.com/hello-world-kian/</guid>
      <pubDate>Wed, 02 Oct 2024 17:08:00 +0200</pubDate>
    </item>
    <item>
      <title><![CDATA[PHP 8.4.0 RC 1 now available for testing - PHP: Hypertext Preprocessor]]></title>
      <description><![CDATA[<div class="clearfix container hero"><img class="hero-logo" src="https://www.php.net/images/logos/php-logo-white.svg" alt="php" width="240" height="120" /><p class="hero-text">A <strong>popular general-purpose scripting language</strong> that is especially suited to web development.<br />Fast, flexible and pragmatic, PHP powers everything from your blog to the most popular websites in the world.</p><p><a href="https://www.php.net/releases/8.3/index.php" class="hero-btn hero-btn-primary">What's new in 8.3</a> <a href="https://www.php.net/downloads.php" class="hero-btn hero-btn-secondary">Download</a></p><ul class="hero-versions"><li class="hero-version"><a class="hero-version-link" href="https://www.php.net/downloads.php#v8.3.12">8.3.12</a> · <a class="notes" href="https://www.php.net/ChangeLog-8.php#8.3.12">Changelog</a> · <a class="notes" href="https://www.php.net/migration83">Upgrading</a></li>
<li class="hero-version"><a class="hero-version-link" href="https://www.php.net/downloads.php#v8.2.24">8.2.24</a> · <a class="notes" href="https://www.php.net/ChangeLog-8.php#8.2.24">Changelog</a> · <a class="notes" href="https://www.php.net/migration82">Upgrading</a></li>
<li class="hero-version"><a class="hero-version-link" href="https://www.php.net/downloads.php#v8.1.30">8.1.30</a> · <a class="notes" href="https://www.php.net/ChangeLog-8.php#8.1.30">Changelog</a> · <a class="notes" href="https://www.php.net/migration81">Upgrading</a></li>
</ul></div><div class="clearfix"><section><div class="home-content"><article class="newsentry"><header class="title"><time datetime="2024-10-10T14:04:23+00:00">10 Oct 2024</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the release of PHP 8.4.0, RC2. This is the second release candidate, continuing the PHP 8.4 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php84">PHP Wiki</a>.</p><p>For source downloads of PHP 8.4.0, RC2 please visit the <a href="https://downloads.php.net/~calvinb">download page</a>.</p><p>Please carefully test this version and report any issues found in the <a href="https://github.com/php/php-src/issues">bug reporting system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.4.0RC2/NEWS">NEWS</a> file or the <a href="https://github.com/php/php-src/blob/php-8.4.0RC2/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be RC 3, planned for 24 October 2024.</p><p>The signatures for the release can be found in <a href="https://gist.github.com/NattyNarwhal/ea2bb82ce1e3fb67f385b2d6e2e085dc">the manifest</a> or on <a href="https://qa.php.net/">the QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></article><article class="newsentry"><header class="title"><time datetime="2024-09-26T19:56:50+00:00">26 Sep 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.1.30. This is a security release.</p><p>All PHP 8.1 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.1.30 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.1.30">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2024-09-26T19:25:27+00:00">26 Sep 2024</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the release of PHP 8.4.0, RC 1. This is the first release candidate, continuing the PHP 8.4 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php84">PHP Wiki</a>.</p><p>For source downloads of PHP 8.4.0, RC 1 please visit the <a href="https://downloads.php.net/~saki">download page</a>.</p><p>Please carefully test this version and report any issues found in the <a href="https://github.com/php/php-src/issues">bug reporting system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.4.0RC1/NEWS">NEWS</a> file or the <a href="https://github.com/php/php-src/blob/php-8.4.0RC1/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be RC 2, planned for 10 October 2024.</p><p>The signatures for the release can be found in <a href="https://gist.github.com/SakiTakamachi/198dac0514f8cba37ed3506526cd1fb2">the manifest</a> or on <a href="https://qa.php.net/">the QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></article><article class="newsentry"><header class="title"><time datetime="2024-09-26T16:25:23+00:00">26 Sep 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.24. This is a security release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.24 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.24">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2024-09-26T13:31:15+00:00">26 Sep 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.3.12. This is a security release.</p><p>All PHP 8.3 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.3.12 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.3.12">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2024-09-12T14:14:49+00:00">12 Sep 2024</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the release of PHP 8.4.0, Beta 5. This is the third beta release, continuing the PHP 8.4 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php84">PHP Wiki</a>.</p><p>For source downloads of PHP 8.4.0, Beta 5 please visit the <a href="https://downloads.php.net/~calvinb">download page</a>.</p><p>Please carefully test this version and report any issues found in the <a href="https://github.com/php/php-src/issues">bug reporting system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.4.0beta5/NEWS">NEWS</a> file or the <a href="https://github.com/php/php-src/blob/php-8.4.0beta5/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be RC 1, planned for 26 September 2024.</p><p>The signatures for the release can be found in <a href="https://gist.github.com/NattyNarwhal/2dc0c8a3f7bf63ec5143b4bf703ee626">the manifest</a> or on <a href="https://qa.php.net/">the QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></article><article class="newsentry"><header class="title"><time datetime="2024-08-29T21:40:58+00:00">29 Aug 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.3.11. This is a bug fix release.</p><p>All PHP 8.3 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.3.11 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.3.11">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2024-08-29T18:15:12+00:00">29 Aug 2024</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the release of PHP 8.4.0, Beta 4. This is the second beta release, continuing the PHP 8.4 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php84">PHP Wiki</a>.</p><p>For source downloads of PHP 8.4.0, Beta 4 please visit the <a href="https://downloads.php.net/~saki">download page</a>.</p><p>Please carefully test this version and report any issues found in the <a href="https://github.com/php/php-src/issues">bug reporting system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.4.0beta4/NEWS">NEWS</a> file or the <a href="https://github.com/php/php-src/blob/php-8.4.0beta4/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be Beta 5, planned for 12 September 2024.</p><p>The signatures for the release can be found in <a href="https://gist.github.com/SakiTakamachi/7132a67e0cdc1e792fa1e88f1726d5cc">the manifest</a> or on <a href="https://qa.php.net/">the QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></article><article class="newsentry"><header class="title"><time datetime="2024-08-29T15:58:02+00:00">29 Aug 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.23. This is a bug fix release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.23 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.23">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2024-08-15T13:45:25+00:00">15 Aug 2024</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the release of PHP 8.4.0, Beta 3. This is the first beta release, continuing the PHP 8.4 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php84">PHP Wiki</a>.</p><p>For source downloads of PHP 8.4.0, Beta 3 please visit the <a href="https://downloads.php.net/~calvinb">download page</a>.</p><p>Please carefully test this version and report any issues found in the <a href="https://github.com/php/php-src/issues">bug reporting system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.4.0beta3/NEWS">NEWS</a> file or the <a href="https://github.com/php/php-src/blob/php-8.4.0beta3/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be Beta 4, planned for 29 August 2024.</p><p>The signatures for the release can be found in <a href="https://gist.github.com/NattyNarwhal/fdd2de9d3b165143d376679258811c15">the manifest</a> or on <a href="https://qa.php.net/">the QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></article><article class="newsentry"><header class="title"><time datetime="2024-08-01T23:21:43+00:00">01 Aug 2024</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the second testing release of PHP 8.4.0, Alpha 4. This continues the PHP 8.4 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php84">PHP Wiki</a>.</p><p>For source downloads of PHP 8.4.0 Alpha 4 please visit the <a href="https://downloads.php.net/~saki/">download page</a>.</p><p>Please carefully test this version and report any issues found in the <a href="https://github.com/php/php-src/issues">bug reporting system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.4.0alpha4/NEWS">NEWS</a> file, or the <a href="https://github.com/php/php-src/blob/php-8.4.0alpha4/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be Beta 1, planned for 15 Aug 2024.</p><p>The signatures for the release can be found in <a href="https://gist.github.com/SakiTakamachi/6ef16057e96947aa030408db244718a7">the manifest</a> or on <a href="https://qa.php.net/">the QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></article><article class="newsentry"><header class="title"><time datetime="2024-08-01T16:12:06+00:00">01 Aug 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.22. This is a bug fix release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.22 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.22">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2024-08-01T13:28:53+00:00">01 Aug 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.3.10. This is a bug fix release.</p><p>All PHP 8.3 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.3.10 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.3.10">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2024-07-18T13:30:46+00:00">18 Jul 2024</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the second testing release of PHP 8.4.0, Alpha 2. This continues the PHP 8.4 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php84">PHP Wiki</a>.</p><p>For source downloads of PHP 8.4.0 Alpha 2 please visit the <a href="https://downloads.php.net/~calvinb/">download page</a>.</p><p>Please carefully test this version and report any issues found in the <a href="https://github.com/php/php-src/issues">bug reporting system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.4.0alpha2/NEWS">NEWS</a> file, or the <a href="https://github.com/php/php-src/blob/php-8.4.0alpha2/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be Alpha 3, planned for 1 Aug 2024.</p><p>The signatures for the release can be found in <a href="https://gist.github.com/NattyNarwhal/74b55b8fcc6411ff8db05f87a6f41864">the manifest</a> or on <a href="https://qa.php.net/">the QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></article><article class="newsentry"><header class="title"><time datetime="2024-07-05T13:22:12+00:00">05 Jul 2024</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the first testing release of PHP 8.4.0, Alpha 1. This starts the PHP 8.4 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php84">PHP Wiki</a>.</p><p>For source downloads of PHP 8.4.0 Alpha 1 please visit the <a href="https://downloads.php.net/~saki/">download page</a>.</p><p>Please carefully test this version and report any issues found using <a href="https://github.com/php/php-src/issues">the bug tracking system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.4.0alpha1/NEWS">NEWS</a> file, or the <a href="https://github.com/php/php-src/blob/php-8.4.0alpha1/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be Alpha 2, planned for 18 Jul 2024.</p><p>The signatures for the release can be found in the <a href="https://gist.github.com/SakiTakamachi/d3e32b780590319bee72d8402593a3ca">manifest</a> or on the <a href="https://qa.php.net/">QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></article><article class="newsentry"><header class="title"><time datetime="2024-07-04T22:59:58+00:00">04 Jul 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.3.9. This is a bug fix release.</p><p>All PHP 8.3 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.3.9 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.3.9">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2024-07-04T14:43:24+00:00">04 Jul 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.21. This is a bug fix release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.21 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.21">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2024-06-06T14:56:47+00:00">06 Jun 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.20. This is a security release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.20 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.20">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2024-06-06T14:42:14+00:00">06 Jun 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.3.8. This is a security release.</p><p>All PHP 8.3 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.3.8 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.3.8">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2024-06-06T14:12:51+00:00">06 Jun 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.1.29. This is a security release.</p><p>All PHP 8.1 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.1.29 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.1.29">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2024-05-09T14:40:06+00:00">09 May 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.3.7. This is a bug fix release.</p><p>All PHP 8.3 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.3.7 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.3.7">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2024-05-09T13:48:33+00:00">09 May 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.19. This is a bug fix release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.19 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.19">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2024-04-24T18:40:29+00:00">24 Apr 2024</time>
</header><div class="newscontent"><p>EDIT 2024-04-25: Clarified when a PHP application is vulnerable to this bug.</p><p>Recently, a bug in <strong>glibc</strong> version 2.39 and older (<a href="https://nvd.nist.gov/vuln/detail/CVE-2024-2961">CVE-2024-2961</a>) was uncovered where a buffer overflow in character set conversions <strong>to</strong> the ISO-2022-CN-EXT character set can result in remote code execution.</p><p>This specific buffer overflow in glibc is exploitable through PHP, which exposes the iconv functionality of glibc to do character set conversions via the <a href="https://www.php.net/manual/en/function.iconv.php">iconv extension</a>. Although the bug is exploitable in the context of the PHP Engine, the bug is not in PHP. It is also not directly exploitable remotely.</p><p>The bug is exploitable, <strong>if and only if</strong>, the PHP application calls iconv <a href="https://www.php.net/manual/en/ref.iconv.php">functions</a> or <a href="https://www.php.net/manual/en/filters.convert.php#filters.convert.iconv">filters</a> with user-supplied character sets.</p><p>Applications are <strong>not</strong> vulnerable if:</p><ul><li>Glibc security updates from the distribution have been installed.</li>
<li>Or the iconv extension is not loaded.</li>
<li>Or the vulnerable character set has been removed from gconv-modules-extra.conf.</li>
<li>Or the application passes only specifically allowed character sets to iconv.</li>
</ul><p>Moreover, when using a user-supplied character set, it is good practice for applications to accept only specific charsets that have been explicitly allowed by the application. One example of how this can be done is by using an allow-list and the <a href="https://www.php.net/manual/en/function.array-search"><code>array_search()</code></a> function to check the encoding before passing it to iconv. For example: <code>array_search($charset, $allowed_list, true)</code></p><p>There are numerous reports online with titles like "Mitigating the iconv Vulnerability for PHP (CVE-2024-2961)" or "PHP Under Attack". These titles are misleading as this is <strong>not</strong> a bug in PHP itself.</p><p>If your PHP application is vulnerable, we first recommend to check if your Linux distribution has already published patched variants of glibc. <a href="https://security-tracker.debian.org/tracker/CVE-2024-2961">Debian</a>, CentOS, and others, have already done so, and please upgrade as soon as possible.</p><p>Once an update is available in glibc, updating that package on your Linux machine will be enough to alleviate the issue. You do not need to update PHP, as glibc is a dynamically linked library.</p><p>If your Linux distribution has not published a patched version of glibc, there is no fix for this issue. However, there exists a workaround described in <a href="https://rockylinux.org/news/glibc-vulnerability-april-2024/">GLIBC Vulnerability on Servers Serving PHP</a> which explains a way on how to remove the problematic character set from glibc. Perform this procedure for every gconv-modules-extra.conf file that is available on your system.</p><p>PHP users on Windows are not affected.</p><p>Therefore, a new version of PHP will not be released for this vulnerability.</p></div></article><article class="newsentry"><header class="title"><time datetime="2024-04-12T15:42:40+00:00">12 Apr 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.1.28. This is a security release.</p><p>All PHP 8.1 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.1.28 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.1.28">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2024-04-11T14:34:04+00:00">11 Apr 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.3.6. This is a security release.</p><p>All PHP 8.3 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.3.6 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.3.6">ChangeLog</a>.</p></div></article></div></section><aside class="tips"><div class="inner"><div class="panel"><div class="body"><p>The PHP Foundation is a collective of people and organizations, united in the mission to ensure the long-term prosperity of the PHP language.</p><p><a href="https://thephp.foundation/donate/" class="btn btn-primary">Donate</a></p></div></div><p class="panel"><a href="https://www.php.net/cal.php">User Group Events</a></p><p class="panel"><a href="https://www.php.net/thanks.php">Special Thanks</a></p></div>
</aside></div>]]></description>
      <link>https://www.php.net/index.php#2024-09-26-3</link>
      <guid>https://www.php.net/index.php#2024-09-26-3</guid>
      <pubDate>Thu, 26 Sep 2024 02:00:00 +0200</pubDate>
    </item>
    <item>
      <title><![CDATA[Increase truncated body in a Guzzle exception - Rob Allen]]></title>
      <description><![CDATA[<p>When Guzzle throws <code>BadResponseException</code>, the message includes information about the method, URL response code and then a truncated part of the body.</p><p>For example:</p><pre class="c1">
"Client error: `GET https://dev.clientproject.com:4444/oauth2/authorize?client_id=983e98d2fab8756a&amp;scope=scope&amp;response_type=code&amp;redirect_uri=%2Fhome&amp;code_challenge=some_code_challenge_here` resulted in a `400 Bad Request` response:
{"error":"invalid_request","error_description":"The request is missing a required parameter, includes an invalid parame (truncated...)
</pre><p>To retrieve the full text of the body, you grab it from the response property of the exception:</p><pre lang="php">
$body = $e-&gt;getResponse()-&gt;getBody()-&gt;getContents();
</pre><p>If you want more text in the exception message you need to pass a handler stack to the <code>Client</code>‘s constructor with an <code>httpErrors</code> middleware that has a <code>BodySummarizer</code> with a larger truncation limit.</p><p>The easiest way to do this is to create the default stack and then modify it:</p><pre lang="php">
use GuzzleHttp\BodySummarizer;
use GuzzleHttp\HandlerStack;
// ...
$stack = HandlerStack::create();
$stack-&gt;remove('http_errors');
$stack-&gt;unshift(Middleware::httpErrors(new BodySummarizer(1500)), 'http_errors');
</pre><p>Set the number of characters to truncate at in the <code>BodySummarizer</code>‘s constructor. I picked <code>1500</code>; the default is <code>120</code> (as of this time of writing).</p><p>After creating the stack, we remove the current <code>httpErrors</code> middleware and add a new one. Note that it needs to be first in the stack as we want it to handle any error from any subsequent middleware too.</p><p>We then create our client with our custom stack:</p><pre lang="php">
use GuzzleHttp\Client;
// ...
$this-&gt;client = new Client([
    'handler'  =&gt; $stack,
    'base_uri' =&gt; $this-&gt;baseUri,
]);
</pre><p>That’s it. There’s now more text in the <code>BadResponseException</code> message.</p>]]></description>
      <link>https://akrabat.com/increase-truncated-body-in-a-guzzle-exception/</link>
      <guid>https://akrabat.com/increase-truncated-body-in-a-guzzle-exception/</guid>
      <pubDate>Tue, 24 Sep 2024 12:00:00 +0200</pubDate>
    </item>
    <item>
      <title><![CDATA[Menciptakan Nuansa Mewah dengan Jasa Desain Interior Bandung - Doug Hill]]></title>
      <description><![CDATA[<p>Setiap orang tentu ingin memiliki hunian yang nyaman dan indah. Namun, menciptakan nuansa mewah di rumah Anda membutuhkan perencanaan yang matang. Banyak faktor yang perlu dipertimbangkan, mulai dari pemilihan material hingga pengaturan pencahayaan.</p>
<p>Di sinilah peran <a href="https://rekakayu.com/jasa-desain-interior-bandung/">jasa desain interior</a> menjadi sangat penting, jasa profesional tidak hanya membantu Anda mewujudkan impian, tetapi juga memastikan setiap detail terlihat mewah dan harmonis. Mari kita bahas lebih dalam bagaimana jasa desain interior Bandung bisa menciptakan nuansa mewah di hunian Anda.</p>
<h2><strong>Cara Jasa Desain Interior Menciptakan Nuansa Mewah</strong></h2>
<h3><strong>1. Pemilihan Material Berkualitas</strong></h3>
<p>Material berkualitas tinggi adalah salah satu kunci utama menciptakan nuansa mewah. Desainer interior akan membantu Anda memilih material yang tahan lama dan elegan, seperti marmer, kayu solid, atau logam berlapis. Bahan-bahan ini tidak hanya meningkatkan tampilan, tetapi juga daya tahan furnitur dan <a href="https://phpaddiction.com/">elemen dekoratif</a> di rumah Anda.</p>
<p>Selain itu, pemilihan material juga harus memperhatikan kesesuaian dengan konsep desain. Material yang tepat akan memberikan kesan eksklusif dan elegan tanpa mengabaikan fungsi. Dengan bantuan jasa desain interior, Anda dapat memastikan pilihan material yang sesuai dengan visi dan anggaran Anda.</p>
<h3><strong>2. Penataan Pencahayaan yang Tepat</strong></h3>
<p>Pencahayaan memainkan peran penting dalam menciptakan suasana mewah. Desainer interior profesional akan membantu Anda merancang sistem pencahayaan yang tidak hanya fungsional, tetapi juga estetis. Pencahayaan yang tepat bisa memperkuat kesan ruangan yang lebih luas dan lebih nyaman.</p>
<p>Pemanfaatan lampu gantung, lampu dinding, atau bahkan pencahayaan tersembunyi bisa membuat perbedaan besar. Jasa desain interior Bandung memastikan bahwa setiap sudut ruangan mendapatkan pencahayaan yang ideal untuk menonjolkan kemewahan desainnya.</p>
<h3><strong>3. Kombinasi Warna yang Harmonis</strong></h3>
<p>Warna memegang peran penting dalam menciptakan suasana mewah. Desainer interior tahu bagaimana mengombinasikan warna-warna netral seperti putih, krem, dan abu-abu dengan sentuhan warna yang lebih tegas. Kombinasi warna ini akan menghasilkan kesan elegan yang tetap hangat.</p>
<p>Pilihan warna yang tepat juga membantu memberikan dimensi pada ruangan Anda. Dengan menggunakan jasa desain interior, Anda akan mendapatkan panduan dalam memilih palet warna yang tidak hanya cantik, tetapi juga memancarkan kemewahan.</p>
<h3><strong>4. Pemanfaatan Ruang Secara Optimal</strong></h3>
<p>Salah satu keahlian desainer interior adalah memaksimalkan ruang yang ada. Mereka akan merancang tata letak yang tidak hanya fungsional tetapi juga estetik. Setiap ruang akan dimanfaatkan dengan baik, sehingga tidak ada sudut yang terbuang.</p>
<p>Dengan jasa desain interior, Anda dapat menciptakan ruang yang terorganisir, rapi, dan mewah. Desainer akan memastikan setiap elemen dekoratif dan furnitur ditempatkan pada posisi yang tepat untuk memaksimalkan keindahan dan kenyamanan ruangan Anda.</p>
<h3><strong>5. Penempatan Aksen Dekoratif yang Menawan</strong></h3>
<p>Aksen dekoratif seperti lukisan, patung, atau hiasan dinding adalah elemen yang tidak boleh diabaikan. Desainer interior akan membantu Anda memilih aksen yang sesuai dengan tema mewah yang ingin Anda hadirkan. Aksen ini bisa menjadi pusat perhatian yang menarik di ruangan Anda.</p>
<p>Aksen dekoratif yang dipilih dengan cermat akan memberikan karakter unik pada ruangan Anda. Dengan jasa desain interior, setiap aksen akan dipadukan secara harmonis untuk menciptakan kesan yang lebih eksklusif.</p>
<h3><strong>6. Pilihan Furnitur yang Elegan</strong></h3>
<p>Furnitur adalah elemen kunci dalam desain interior. Jasa desain interior membantu Anda memilih furnitur yang tidak hanya nyaman tetapi juga elegan. Penggunaan furnitur dengan desain yang unik dan berkualitas tinggi akan menambah kesan mewah pada hunian Anda.</p>
<p>Pemilihan furnitur juga harus sesuai dengan tema dan gaya desain yang diinginkan. Desainer interior akan membantu Anda menemukan furnitur yang mampu memadukan kenyamanan, fungsi, dan estetika dengan sempurna.</p>
<h2><strong>Mewujudkan Hunian Mewah dengan Sentuhan Profesional</strong></h2>
<p>Jika Anda ingin menciptakan hunian mewah dengan nuansa yang elegan, bantuan jasa desain interior profesional adalah pilihan yang tepat. Mereka tidak hanya membantu Anda dalam merancang konsep, tetapi juga merealisasikan visi Anda menjadi kenyataan. Setiap detail diperhatikan agar sesuai dengan keinginan dan anggaran Anda.</p>
<p>Dengan bekerja sama dengan jasa desain interior Bandung, Anda bisa mendapatkan hunian yang mencerminkan kemewahan dan kenyamanan. Dari pemilihan material hingga penataan ruang, desainer interior akan memastikan hasil akhir yang memuaskan.</p>
<p>Jika Anda tertarik untuk mewujudkan hunian mewah, <a href="https://rekakayu.com/">Reka Kayu</a> siap membantu Anda dengan sentuhan desain interior yang unik dan eksklusif. Dengan pengalaman dan keahlian, Reka Kayu memastikan setiap proyek dikerjakan dengan teliti dan profesional.</p>]]></description>
      <link>https://phpaddiction.com/menciptakan-nuansa-mewah-dengan-jasa-desain-interior-bandung/</link>
      <guid>https://phpaddiction.com/menciptakan-nuansa-mewah-dengan-jasa-desain-interior-bandung/</guid>
      <pubDate>Thu, 19 Sep 2024 17:24:00 +0200</pubDate>
    </item>
    <item>
      <title><![CDATA[Fixing PhpStorm cannot find a local copy of Standard Input Code - Rob Allen]]></title>
      <description><![CDATA[<p>Recently, I set up my PHP dev environment to allow me to step debug from unit tests that I run with <code>make unit</code></p><p>The relevant parts of <code>Makefile</code> look like this:</p><pre>
# Set DEBUG=1 to enable Xdebug
ifeq ($(origin DEBUG),undefined)
    XDEBUG :=
else
    XDEBUG := XDEBUG_SESSION=PHPSTORM
endif
unit: ## Run unit tests
        docker compose exec php bash -c "$(XDEBUG) vendor/bin/phpunit --testsuite=unit"
</pre><p>I can now set a break point and run the unit tests with Xdebug enabled with <code>DEBUG=1 make unit</code>.</p><p>I have an environment variable set in <code>compose.yaml</code>: <code>PHP_IDE_CONFIG=serverName=project.com.localhost</code> and I use to set up the mappings in PhpStorm’s settings. As we’re using Docker, I also have <code>xdebug.client_host = host.docker.internal</code> set up in my PHP ini settings.</p><p>I noticed that when I didn’t have a breakpoint set, PhpStorm would break with this error in Debug console for a particular test:</p><p><img src="https://akrabat.com/wp-content/uploads/2024/08/2024-08-20-phpstorm-debug.png" alt="Screen shot of PhpStorm with the words &quot;Cannot find a local copy of the file on server /var/www/html/Standard input code&quot;" title="2024-08-20-phpstorm-debug.png" border="0" width="600" /></p><p>That’s a strange error message: “Cannot find a local copy of the file on server /var/www/html/Standard input code”! Clearly I don’t have a file called “Standard input code” and so it’s not surprising that PhpStorm can’t map to it.</p><p>Google to the rescue!</p><p>I eventually worked out that it’s related to having a test with the <code>@runInSeparateProcess</code> annotation. As a result, phpunit does some magic and Xdebug sends through a file that it has labeled as “Standard input code” – presumably as it was injected via stdin..</p><p>To fix this, I disabled these PhpStorm settings in PHP -&gt; Debug:</p><ul><li>“Break at first line in PHP scripts” in the External connections section</li>
<li>“Force break at first line when no path mapping specified” in the Xdebug section</li>
</ul><p>In PhpStorm 2024, it looks like this:</p><p><img src="https://akrabat.com/wp-content/uploads/2024/08/2024-08-20-phpstorm-settings.png" alt="2024 08 20 phpstorm settings." title="2024-08-20-phpstorm-settings.png" border="0" width="600" height="476" /></p><p>Of course, you’ll have to manually set up path mappings in PHP -&gt; Servers, but I do that anyway, so not really a problem for me, at least.</p><p>Problem solved!</p>]]></description>
      <link>https://akrabat.com/fixing-phpstorm-cannot-find-a-local-copy-of-standard-input-code/</link>
      <guid>https://akrabat.com/fixing-phpstorm-cannot-find-a-local-copy-of-standard-input-code/</guid>
      <pubDate>Tue, 17 Sep 2024 12:00:00 +0200</pubDate>
    </item>
    <item>
      <title><![CDATA[Pipelined database operation performance redux with python-oracledb: very impressive - Christopher Jones]]></title>
      <description><![CDATA[<div><div></div><p id="80fb" class="pw-post-body-paragraph mh mi gu mj b mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne gn bk">In <a class="af nf" href="https://medium.com/@cjones-oracle/pipelined-database-operations-with-python-oracledb-2-4-dd8bfbdadf0d" rel="noopener">Pipelined database operations with python-oracledb 2.4</a> I gave a simple benchmark showing the performance benefit of Oracle Database 23ai Pipelining. We now have results which are even more impressive.</p><figure class="nj nk nl nm nn no ng nh paragraph-image"><div role="button" tabindex="0" class="np nq fj nr bh ns"><div class="ng nh ni"><picture><source srcset="https://miro.medium.com/v2/resize:fit:640/format:webp/0*bH0T9AHbXf8Ffvy0 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/0*bH0T9AHbXf8Ffvy0 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/0*bH0T9AHbXf8Ffvy0 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/0*bH0T9AHbXf8Ffvy0 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/0*bH0T9AHbXf8Ffvy0 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/0*bH0T9AHbXf8Ffvy0 1100w, https://miro.medium.com/v2/resize:fit:1400/format:webp/0*bH0T9AHbXf8Ffvy0 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" type="image/webp" /><source data-testid="og" srcset="https://miro.medium.com/v2/resize:fit:640/0*bH0T9AHbXf8Ffvy0 640w, https://miro.medium.com/v2/resize:fit:720/0*bH0T9AHbXf8Ffvy0 720w, https://miro.medium.com/v2/resize:fit:750/0*bH0T9AHbXf8Ffvy0 750w, https://miro.medium.com/v2/resize:fit:786/0*bH0T9AHbXf8Ffvy0 786w, https://miro.medium.com/v2/resize:fit:828/0*bH0T9AHbXf8Ffvy0 828w, https://miro.medium.com/v2/resize:fit:1100/0*bH0T9AHbXf8Ffvy0 1100w, https://miro.medium.com/v2/resize:fit:1400/0*bH0T9AHbXf8Ffvy0 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" /></picture></div></div><figcaption class="nu ff nv ng nh nw nx bf b bg z du">Photo by <a class="af nf" href="https://unsplash.com/@mattpaul?utm_source=medium&amp;utm_medium=referral" rel="noopener ugc nofollow" target="_blank">Matt Paul Catalano</a> on <a class="af nf" href="https://unsplash.com/?utm_source=medium&amp;utm_medium=referral" rel="noopener ugc nofollow" target="_blank">Unsplash</a></figcaption></figure><p id="334d" class="pw-post-body-paragraph mh mi gu mj b mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne gn bk">The system testing team (thank you!) ran a performance evaluation with Python 3.12 and python-oracledb 2.4.1 using the same schema they had used for their ODP.NET Pipelining benchmark (discussed <a class="af nf" href="https://medium.com/@alex.keh/asynchronous-odp-net-and-pipelining-improve-performance-by-reducing-latency-f7314a6970be" rel="noopener">here</a>).</p><p id="e405" class="pw-post-body-paragraph mh mi gu mj b mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne gn bk">The app used 100 threads that repeatedly executed different SELECT statements. The tests measured performance metrics over 20,000 iterations with pipelining enabled versus pipelining disabled:</p><ul class=""><li id="bbaa" class="mh mi gu mj b mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne ny nz oa bk">Pipelining runs finished <strong class="mj gv">530% faster</strong> on average.</li><li id="26a2" class="mh mi gu mj b mk ob mm mn mo oc mq mr ms od mu mv mw oe my mz na of nc nd ne ny nz oa bk">Pipelining runs performed <strong class="mj gv">529% more transactions per second</strong>.</li><li id="d833" class="mh mi gu mj b mk ob mm mn mo oc mq mr ms od mu mv mw oe my mz na of nc nd ne ny nz oa bk">Pipelining runs performed <strong class="mj gv">52% more transactions per second per processor</strong>.</li></ul><p id="33e1" class="pw-post-body-paragraph mh mi gu mj b mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne gn bk">I’m not sure I think that last stat is what it says it is, or that it is useful, but I include it for completeness with the ODP.NET results. Regardless the time and TPS figures are very significant!</p><p id="ec70" class="pw-post-body-paragraph mh mi gu mj b mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne gn bk">One interesting, but obvious when you think about it, note is that client CPU usage increases with Pipelining because the client is able to be kept busy and do more work.</p><h2 id="63be" class="og oh gu bf oi oj ok dy ol om on ea oo ms op oq or mw os ot ou na ov ow ox oy bk">Resources</h2><ul class=""><li id="38c8" class="mh mi gu mj b mk oz mm mn mo pa mq mr ms pb mu mv mw pc my mz na pd nc nd ne ny nz oa bk">Blog: <a class="af nf" href="https://medium.com/@cjones-oracle/pipelined-database-operations-with-python-oracledb-2-4-dd8bfbdadf0d" rel="noopener">Pipelined database operations with python-oracledb 2.4</a></li><li id="9ee4" class="mh mi gu mj b mk ob mm mn mo oc mq mr ms od mu mv mw oe my mz na of nc nd ne ny nz oa bk">Doc: <a class="af nf" href="https://python-oracledb.readthedocs.io/en/latest/user_guide/asyncio.html#pipelining-database-operations" rel="noopener ugc nofollow" target="_blank">Pipelining Database Operations</a></li></ul></div>]]></description>
      <link>https://medium.com/oracledevs/pipelined-database-operation-performance-redux-with-python-oracledb-very-impressive-59cf4ba6a1ac?source=rss-adc937c3a9d------2</link>
      <guid>https://medium.com/oracledevs/pipelined-database-operation-performance-redux-with-python-oracledb-very-impressive-59cf4ba6a1ac?source=rss-adc937c3a9d------2</guid>
      <pubDate>Thu, 12 Sep 2024 09:27:00 +0200</pubDate>
    </item>
    <item>
      <title><![CDATA[PHP 8.4.0 Beta 5 available for testing - PHP: Hypertext Preprocessor]]></title>
      <description><![CDATA[<div><header class="title"><time datetime="2024-09-12T14:14:49+00:00">12 Sep 2024</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the release of PHP 8.4.0, Beta 5. This is the third beta release, continuing the PHP 8.4 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php84">PHP Wiki</a>.</p><p>For source downloads of PHP 8.4.0, Beta 5 please visit the <a href="https://downloads.php.net/~calvinb">download page</a>.</p><p>Please carefully test this version and report any issues found in the <a href="https://github.com/php/php-src/issues">bug reporting system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.4.0beta5/NEWS">NEWS</a> file or the <a href="https://github.com/php/php-src/blob/php-8.4.0beta5/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be RC 1, planned for 26 September 2024.</p><p>The signatures for the release can be found in <a href="https://gist.github.com/NattyNarwhal/2dc0c8a3f7bf63ec5143b4bf703ee626">the manifest</a> or on <a href="https://qa.php.net/">the QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></div><div><header class="title"><time datetime="2024-08-29T21:40:58+00:00">29 Aug 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.3.11. This is a bug fix release.</p><p>All PHP 8.3 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.3.11 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.3.11">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-08-29T18:15:12+00:00">29 Aug 2024</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the release of PHP 8.4.0, Beta 4. This is the second beta release, continuing the PHP 8.4 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php84">PHP Wiki</a>.</p><p>For source downloads of PHP 8.4.0, Beta 4 please visit the <a href="https://downloads.php.net/~saki">download page</a>.</p><p>Please carefully test this version and report any issues found in the <a href="https://github.com/php/php-src/issues">bug reporting system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.4.0beta4/NEWS">NEWS</a> file or the <a href="https://github.com/php/php-src/blob/php-8.4.0beta4/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be Beta 5, planned for 12 September 2024.</p><p>The signatures for the release can be found in <a href="https://gist.github.com/SakiTakamachi/7132a67e0cdc1e792fa1e88f1726d5cc">the manifest</a> or on <a href="https://qa.php.net/">the QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></div><div><header class="title"><time datetime="2024-08-29T15:58:02+00:00">29 Aug 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.23. This is a bug fix release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.23 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.23">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-08-15T13:45:25+00:00">15 Aug 2024</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the release of PHP 8.4.0, Beta 3. This is the first beta release, continuing the PHP 8.4 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php84">PHP Wiki</a>.</p><p>For source downloads of PHP 8.4.0, Beta 3 please visit the <a href="https://downloads.php.net/~calvinb">download page</a>.</p><p>Please carefully test this version and report any issues found in the <a href="https://github.com/php/php-src/issues">bug reporting system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.4.0beta3/NEWS">NEWS</a> file or the <a href="https://github.com/php/php-src/blob/php-8.4.0beta3/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be Beta 4, planned for 29 August 2024.</p><p>The signatures for the release can be found in <a href="https://gist.github.com/NattyNarwhal/fdd2de9d3b165143d376679258811c15">the manifest</a> or on <a href="https://qa.php.net/">the QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></div><div><header class="title"><time datetime="2024-08-01T23:21:43+00:00">01 Aug 2024</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the second testing release of PHP 8.4.0, Alpha 4. This continues the PHP 8.4 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php84">PHP Wiki</a>.</p><p>For source downloads of PHP 8.4.0 Alpha 4 please visit the <a href="https://downloads.php.net/~saki/">download page</a>.</p><p>Please carefully test this version and report any issues found in the <a href="https://github.com/php/php-src/issues">bug reporting system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.4.0alpha4/NEWS">NEWS</a> file, or the <a href="https://github.com/php/php-src/blob/php-8.4.0alpha4/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be Beta 1, planned for 15 Aug 2024.</p><p>The signatures for the release can be found in <a href="https://gist.github.com/SakiTakamachi/6ef16057e96947aa030408db244718a7">the manifest</a> or on <a href="https://qa.php.net/">the QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></div><div><header class="title"><time datetime="2024-08-01T16:12:06+00:00">01 Aug 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.22. This is a bug fix release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.22 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.22">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-08-01T13:28:53+00:00">01 Aug 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.3.10. This is a bug fix release.</p><p>All PHP 8.3 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.3.10 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.3.10">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-07-18T13:30:46+00:00">18 Jul 2024</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the second testing release of PHP 8.4.0, Alpha 2. This continues the PHP 8.4 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php84">PHP Wiki</a>.</p><p>For source downloads of PHP 8.4.0 Alpha 2 please visit the <a href="https://downloads.php.net/~calvinb/">download page</a>.</p><p>Please carefully test this version and report any issues found in the <a href="https://github.com/php/php-src/issues">bug reporting system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.4.0alpha2/NEWS">NEWS</a> file, or the <a href="https://github.com/php/php-src/blob/php-8.4.0alpha2/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be Alpha 3, planned for 1 Aug 2024.</p><p>The signatures for the release can be found in <a href="https://gist.github.com/NattyNarwhal/74b55b8fcc6411ff8db05f87a6f41864">the manifest</a> or on <a href="https://qa.php.net/">the QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></div><div><header class="title"><time datetime="2024-07-05T13:22:12+00:00">05 Jul 2024</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the first testing release of PHP 8.4.0, Alpha 1. This starts the PHP 8.4 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php84">PHP Wiki</a>.</p><p>For source downloads of PHP 8.4.0 Alpha 1 please visit the <a href="https://downloads.php.net/~saki/">download page</a>.</p><p>Please carefully test this version and report any issues found using <a href="https://github.com/php/php-src/issues">the bug tracking system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.4.0alpha1/NEWS">NEWS</a> file, or the <a href="https://github.com/php/php-src/blob/php-8.4.0alpha1/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be Alpha 2, planned for 18 Jul 2024.</p><p>The signatures for the release can be found in the <a href="https://gist.github.com/SakiTakamachi/d3e32b780590319bee72d8402593a3ca">manifest</a> or on the <a href="https://qa.php.net/">QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></div><div><header class="title"><time datetime="2024-07-04T22:59:58+00:00">04 Jul 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.3.9. This is a bug fix release.</p><p>All PHP 8.3 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.3.9 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.3.9">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-07-04T14:43:24+00:00">04 Jul 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.21. This is a bug fix release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.21 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.21">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-06-06T14:56:47+00:00">06 Jun 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.20. This is a security release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.20 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.20">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-06-06T14:42:14+00:00">06 Jun 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.3.8. This is a security release.</p><p>All PHP 8.3 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.3.8 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.3.8">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-06-06T14:12:51+00:00">06 Jun 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.1.29. This is a security release.</p><p>All PHP 8.1 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.1.29 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.1.29">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-05-09T14:40:06+00:00">09 May 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.3.7. This is a bug fix release.</p><p>All PHP 8.3 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.3.7 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.3.7">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-05-09T13:48:33+00:00">09 May 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.19. This is a bug fix release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.19 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.19">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-04-24T18:40:29+00:00">24 Apr 2024</time>
</header><div class="newscontent"><p>EDIT 2024-04-25: Clarified when a PHP application is vulnerable to this bug.</p><p>Recently, a bug in <strong>glibc</strong> version 2.39 and older (<a href="https://nvd.nist.gov/vuln/detail/CVE-2024-2961">CVE-2024-2961</a>) was uncovered where a buffer overflow in character set conversions <strong>to</strong> the ISO-2022-CN-EXT character set can result in remote code execution.</p><p>This specific buffer overflow in glibc is exploitable through PHP, which exposes the iconv functionality of glibc to do character set conversions via the <a href="https://www.php.net/manual/en/function.iconv.php">iconv extension</a>. Although the bug is exploitable in the context of the PHP Engine, the bug is not in PHP. It is also not directly exploitable remotely.</p><p>The bug is exploitable, <strong>if and only if</strong>, the PHP application calls iconv <a href="https://www.php.net/manual/en/ref.iconv.php">functions</a> or <a href="https://www.php.net/manual/en/filters.convert.php#filters.convert.iconv">filters</a> with user-supplied character sets.</p><p>Applications are <strong>not</strong> vulnerable if:</p><ul><li>Glibc security updates from the distribution have been installed.</li>
<li>Or the iconv extension is not loaded.</li>
<li>Or the vulnerable character set has been removed from gconv-modules-extra.conf.</li>
<li>Or the application passes only specifically allowed character sets to iconv.</li>
</ul><p>Moreover, when using a user-supplied character set, it is good practice for applications to accept only specific charsets that have been explicitly allowed by the application. One example of how this can be done is by using an allow-list and the <a href="https://www.php.net/manual/en/function.array-search"><code>array_search()</code></a> function to check the encoding before passing it to iconv. For example: <code>array_search($charset, $allowed_list, true)</code></p><p>There are numerous reports online with titles like "Mitigating the iconv Vulnerability for PHP (CVE-2024-2961)" or "PHP Under Attack". These titles are misleading as this is <strong>not</strong> a bug in PHP itself.</p><p>If your PHP application is vulnerable, we first recommend to check if your Linux distribution has already published patched variants of glibc. <a href="https://security-tracker.debian.org/tracker/CVE-2024-2961">Debian</a>, CentOS, and others, have already done so, and please upgrade as soon as possible.</p><p>Once an update is available in glibc, updating that package on your Linux machine will be enough to alleviate the issue. You do not need to update PHP, as glibc is a dynamically linked library.</p><p>If your Linux distribution has not published a patched version of glibc, there is no fix for this issue. However, there exists a workaround described in <a href="https://rockylinux.org/news/glibc-vulnerability-april-2024/">GLIBC Vulnerability on Servers Serving PHP</a> which explains a way on how to remove the problematic character set from glibc. Perform this procedure for every gconv-modules-extra.conf file that is available on your system.</p><p>PHP users on Windows are not affected.</p><p>Therefore, a new version of PHP will not be released for this vulnerability.</p></div></div><div><header class="title"><time datetime="2024-04-12T15:42:40+00:00">12 Apr 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.1.28. This is a security release.</p><p>All PHP 8.1 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.1.28 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.1.28">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-04-11T14:34:04+00:00">11 Apr 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.3.6. This is a security release.</p><p>All PHP 8.3 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.3.6 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.3.6">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-04-11T13:37:51+00:00">11 Apr 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.18. This is a security release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.18 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.18">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-03-14T21:02:45+00:00">14 Mar 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.3.4. This is a bug fix release.</p><p>All PHP 8.3 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.3.4 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.3.4">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-03-14T15:21:29+00:00">14 Mar 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.17. This is a bug fix release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.17 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.17">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-02-15T13:36:20-05:00">15 Feb 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.16. This is a bug fix release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.16 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.16">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-02-15T15:48:46+00:00">15 Feb 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.3.3. This is a bug fix release.</p><p>All PHP 8.3 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.3.3 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.3.3">ChangeLog</a>.</p></div></div>]]></description>
      <link>https://www.php.net/index.php#2024-09-12-1</link>
      <guid>https://www.php.net/index.php#2024-09-12-1</guid>
      <pubDate>Thu, 12 Sep 2024 02:00:00 +0200</pubDate>
    </item>
    <item>
      <title><![CDATA[Installing the SQL Server PHP extension in Docker on Mac - Rob Allen]]></title>
      <description><![CDATA[<p>I’m working on a project that uses MS SQL Server as its database. Recently, I noticed that the <a href="https://devblogs.microsoft.com/azure-sql/development-with-sql-in-containers-on-macos/">SQL Server Docker container now works with Apple Silicon Macs</a>, so looked into setting up a PHP-FPM container with the <code>sqlsrv</code> extension installed.</p><p>I’m noting the relevant parts of my <code>Dockerfile</code> for when I need them again, so this is entirely an aide-mémoire!</p><pre lang="Dockerfile">
FROM ubuntu:22.04
# Install PHP as per https://akrabat.com/7126
## Register the Microsoft package repository
RUN curl https://packages.microsoft.com/keys/microsoft.asc | tee /etc/apt/trusted.gpg.d/microsoft.asc \
    &amp;&amp; curl https://packages.microsoft.com/config/debian/11/prod.list | tee /etc/apt/sources.list.d/mssql-release.list \
    &amp;&amp; apt-get update
# Install the ODBC libraries and MS command line tools
RUN ACCEPT_EULA=Y apt-get install -y unixodbc-dev msodbcsql18 mssql-tools18
# Install sqlsrv and pdo_sqlsrv PHP extensions
RUN pecl install sqlsrv \
    &amp;&amp; pecl install pdo_sqlsrv \
    &amp;&amp; echo "extension=sqlsrv.so" &gt; /etc/php/8.2/mods-available/sqlsrv.ini \
    &amp;&amp; echo "extension=pdo_sqlsrv.so" &gt; /etc/php/8.2/mods-available/pdo_sqlsrv.ini \
    &amp;&amp; phpenmod -v 8.2 sqlsrv pdo_sqlsrv \
    &amp;&amp; apt-get clean \
    &amp;&amp; rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
# Other stuff, such as copying over settings files and starting PHP-FPM
</pre><p>It all works remarkably well and makes development that much easier. There are two key MS libraries needed: <code>msodbcsql18</code> for the PHP extensions and <code>mssql-tools18</code> installs <code>/opt/mssql-tools18/bin/sqlcmd</code>, the CLI tool for SQL Server.</p><h3 id="configuring-sql-server-in-docker-compose">Configuring SQL Server in Docker Compose</h3><p>To run SQL Server on an Apple Silicon Mac you need to enable Rosetta in Docker Desktop and then configure a few environment variables. This is how I set the <code>db</code> service in <code>compose.yaml</code>:</p><pre lang="yaml">
  db:
      platform: linux/amd64
      image: mcr.microsoft.com/mssql/server:2022-latest
      environment:
        ACCEPT_EULA: 'Y'
        MSSQL_PID: 'Developer'
        MSSQL_SA_PASSWORD: 'Password123!'
        MSSQL_TCP_PORT: 1433
      ports:
        - "1433:1433"
      volumes:
        - ./opt/mssql:/var/opt/mssql
</pre><p>We set <code>plaform</code> to remove an annoying warning, but as there isn’t an ARM64 container for full SQL Server, the warning doesn’t help.</p><p>The environment variables set are:</p><ul><li><code>ACCEPT_EULA</code>: Must be <code>Y</code> otherwise nothing works :)</li>
<li><code>MSSQL_PID</code>: Set to <code>Developer</code> for the developer licence, unless you have a another license.</li>
<li><code>MSSQL_SA_PASSWORD</code>: The root password (The <code>sa</code> user in SQL Server’s world)</li>
<li><code>MSSQL_TCP_PORT</code>: Not needed as it defaults to 1433, but a useful reminder.</li>
</ul><p>The default <code>MSSQL_DATA_DIR</code> directory on Linux is <code>/var/opt/mssql</code>, so I map that to the <code>opt/mssql</code> directory in my project, which is registered in <code>.gitignore</code>.</p>]]></description>
      <link>https://akrabat.com/installing-the-sql-server-php-extension-in-docker-on-mac/</link>
      <guid>https://akrabat.com/installing-the-sql-server-php-extension-in-docker-on-mac/</guid>
      <pubDate>Tue, 10 Sep 2024 12:00:00 +0200</pubDate>
    </item>
    <item>
      <title><![CDATA[Xdebug Update: August 2024 - Derick Rethans]]></title>
      <description><![CDATA[<p>In this monthly update I explain what happened with Xdebug development</p><p><a href="https://github.com/sponsors/derickr/">GitHub</a> and <a href="https://xdebug.org/support">Pro/Business supporters</a> will get it earlier, around the first of each month.</p><p>On GitHub sponsors, I am currently 32% towards my $2,500 per month goal, which is set to allow continued <strong>maintenance</strong> of Xdebug. This is again less than last month.</p><p>If you are leading a team or company, then it is also possible to support Xdebug through <a href="https://xdebug.org/support">a subscription</a>.</p><p>In the last month, I spend around 8 hours on Xdebug, with 20 hours funded. I also spent 8.5 hours on the Native Path Mapping project.</p><div class="articleSubSection"><h2>PHP 8.4</h2><p>The large change for the <a href="https://wiki.php.net/rfc/exit-as-function">exit-as-a-function</a> proposal has been merged into PHP, which means I had to spend some time finishing and tidying up a Pull Request that Tim Düsterhus had provided.</p><p>I also improved Xdebug's <a href="https://xdebug.org/ci">CI</a> so that it can run as a separate user.</p><p>Right now, there don't seem to be any outstanding issues with PHP 8.4 so I will soon create another alpha (or beta) release so that you can try out Xdebug with the latest beta versions of PHP 8.4's.</p></div><div class="articleSubSection"><h2>Native Xdebug Path Mapping</h2><p>I continued with the <a href="https://xdebug.org/funding/001-native-path-mapping">Native Xdebug Path Mapping</a> project.</p><p>This is a separately funded project, I don't classify the hours that I worked on this in "Xdebug Hours". I also publish a separate report on the <a href="https://xdebug.org/funding/001-native-path-mapping">project page</a>.</p><p>Again, I am including it here:</p><p>I continued with the parser to parse the path mapping files. The parsing is now finished, although I do still need to modify how the parsed information is stored. Right now, the data structures are not optimised to be able to do line mapping as well.</p><p>Because the parser parsers user input, it is important that the parser is rubust. It should be able to handle correctly formatted files, but also files with errors.</p><p>It is not always possible to come up with all the failure situations by thinking, and therefore a common technique is to use a fuzzer. For PHP there is <a href="https://infection.github.io/">Infection PHP</a> for mutation testing for example. For C, and C++, a commonly used tool is <a href="https://github.com/AFLplusplus/AFLplusplus">AFL++</a>. This provides a compiler wrapper and a run-time to fuzz the input to your application. You first provide a template, which it then modifies to try to break your code.</p><p>The template that I used in this case was a minimal map file:</p><pre>remote_prefix: /usr/local/www
local_prefix: /home/derick/project
/projects/example.php:5-17 = /example.php:8
/example.php:5-17 = /example.php:8-20
/example.php:17 = /example.php:20
/projects/php-web/ = /php-web/
</pre><p>In addition to the template you also need to provide a shim — the program that in my case takes the argument given to it and then parses that as a file. The AFL++ tool's compiler wrapper adds some magic to it to be able to catch errors.</p><p>When you then run the fuzzer, such as with:</p><pre>AFL_SKIP_CPUFREQ=1 afl-fuzz -b 7 -i fuzz-seeds -o fuzz-output -- ./afl-test @@
</pre><p>It then runs your program with your template files (in fuzz-seeds in my example). And then also with loads of variants.</p><p>The fuzzer found a few errors in my parser, which ended up crashing it. One such examples that I hadn't thought of is of a line starting with a =:</p><pre>remote_prefix: /usr/local/www
local_prefix: /home/derick/project
=/example.php:42-5 = /example.php
</pre><p>You can find the other cases it found in a <a href="https://github.com/derickr/xdebug/blob/001-native-path-mapping/tests/ctest/fuzz-cases.cpp#L93">dedicated test file</a>.</p><p>In September I hope to finish the parser (by storing things more efficiently internally) as well as creating APIs to do the mapping.</p></div><div class="articleSubSection"><h2>Xdebug Videos</h2><p>I have created no new videos since last month, but you can see all the previous ones on my <a href="https://www.youtube.com/playlist?list=PLg9Kjjye-m1g_eXpdaifUqLqALLqZqKd4">channel</a>.</p><p>If you have any suggestions, feel free to reach out to <a href="https://phpc.social/@derickr">me on Mastodon</a> or via <a href="http://derickrethans/who.html">email</a>.</p></div><div class="articleSubSection"><h2>Business Supporter Scheme and Funding</h2><p>In the last month, no new business supporters signed up.</p><p>Besides business support, I also maintain a <a href="https://www.patreon.com/derickr">Patreon</a> page, a profile on <a href="https://github.com/sponsors/derickr">GitHub sponsors</a>, as well as an <a href="https://opencollective.com/xdebug">OpenCollective</a> organisation.</p><p>If you want to contribute to specific projects, you can find those on the <a href="https://xdebug.org/funding">Projects</a> page.</p></div><div class="articleSubSection"><h2>Xdebug Cloud</h2><p>Xdebug Cloud is the <em>Proxy As A Service</em> platform to allow for debugging in more scenarios, where it is hard, or impossible, to have Xdebug make a connection to the IDE. It is continuing to operate as Beta release.</p><p>Packages start at £49/month, and I have recently introduced a package for larger companies. This has a larger initial set of tokens, and discounted extra tokens.</p><p>If you want to be kept up to date with Xdebug Cloud, please sign up to the <a href="https://xdebug.cloud/newsletter">mailinglist</a>, which I will use to send out an update not more than once a month.</p></div>]]></description>
      <link>https://derickrethans.nl/xdebug-update-august-2024.html</link>
      <guid>https://derickrethans.nl/xdebug-update-august-2024.html</guid>
      <pubDate>Tue, 03 Sep 2024 15:35:00 +0200</pubDate>
    </item>
    <item>
      <title><![CDATA[Prevent the Docker container from taking 10 seconds to stop - Rob Allen]]></title>
      <description><![CDATA[<p>For one project that I’m working on the PHP-FPM-based Docker container is built from a Ubuntu container with PHP is installed into it.</p><p>A little like this:</p><pre lang="Dockerfile">
FROM ubuntu:22.04
RUN apt-get update &amp;&amp; apt-get upgrade -y &amp;&amp; apt-get install -y gnupg curl
# Register the Ondrej package repo for PHP
RUN mkdir -p /etc/apt/keyrings \
    curl -sS 'https://keyserver.ubuntu.com/pks/lookup?op=get&amp;search=0x14aa40ec0831756756d7f66c4f4ea0aae5267a6c' | gpg --dearmor | tee /etc/apt/keyrings/ppa_ondrej_php.gpg &gt; /dev/null \
    &amp;&amp; echo "deb [signed-by=/etc/apt/keyrings/ppa_ondrej_php.gpg] https://ppa.launchpadcontent.net/ondrej/php/ubuntu jammy main" &gt; /etc/apt/sources.list.d/ppa_ondrej_php.list \
    &amp;&amp; apt-get update
# Install PHP
RUN apt-get install -y php8.2-cli php8.2-fpm php8.2-dev \
       php8.2-sqlite3 php8.2-gd php8.2-intl php8.2-imagick \
       php8.2-mbstring php8.2-xml php8.2-zip php8.2-bcmath \
       php8.2-curl php8.2-pdo php8.2-opcache php8.2-gettext \
       php-pear
# other stuff, such as copying over settings files
# Run php-fpm
WORKDIR /var/www/html
EXPOSE 9000
CMD /usr/sbin/php-fpm8.2 -F -R
</pre><p>This works fine, however, when stopping the containers with <code>docker compose down</code>, I noticed that it takes 10 seconds for the PHP container to stop:</p><pre>
$ docker compose down
[+] Running 5/5
 ✔ Container portal-web-1   Removed                            0.1s 
 ✔ Container portal-db-1    Removed                            0.3s 
 ✔ Container portal-mail-1  Removed                            0.1s 
 ✔ Container portal-php-1   Removed                           10.1s 
 ✔ Network portal_default   Removed                            0.0s 
</pre><p>Googling around, it seems that 10 seconds is a Docker timeout, so it seems that the PHP container isn’t shutting down itself, but is being killed by Docker.</p><p>Further googling and many tests later, I found that the solution is to use <a href="https://docs.docker.com/reference/dockerfile/#exec-form">exec form</a> for the CMD:</p><pre lang="Dockerfile">
CMD ["/usr/sbin/php-fpm8.2", "-F", "-R"]
</pre><p>Once I had made this change, stopping the PHP container takes 0.1s as I would hope:</p><pre>
$ docker compose down
[+] Running 5/5
 ✔ Container portal-web-1   Removed                            0.2s 
 ✔ Container portal-mail-1  Removed                            0.1s 
 ✔ Container portal-db-1    Removed                            0.3s 
 ✔ Container portal-php-1   Removed                            0.1s 
 ✔ Network portal_default   Removed                            0.0s 
</pre><p>Much better!</p><h3 id="aside-why-does-this-work">Aside: why does this work?</h3><p>The underlying reason is the way unix-like operations systems handle termination of processes. When a process needs to terminate via say a SIGTERM signal, it will terminate and become one of those “zombie” processes that you sometimes see when you type <code>ps</code>. It’s parent process then “waits on” (or “reaps”) it for the exit code and then it is really gone. If that process that’s been terminated has children, then they now no longer have a parent and so the <code>init</code> process (PID 1) takes them over (“adopts” them) and all is well with the system.</p><p>With Docker however, we usually run our process as PID 1 and we need this process to correctly reap child processes and adopt orphans (i.e. act like <code>init</code>). Specifically, <code>CMD /usr/sbin/php-fpm8.2 -F -R</code> will start Bash as PID 1 and then php-fpm as a child. This seems to be fine as Bash can reap and adopt processes, except that <em>Bash doesn’t handle signals properly</em>!</p><p>On shutdown, Docker sends SIGTERM to Bash, which terminates. However, Bash, <em>does not</em> send SIGTERM to its child processes (php-fpm in this case) and so it sits there waiting php-fpm to terminate. As php-fpm doesn’t know that it needs to terminate, we have to wait 10 seconds until Docker gets bored and kills the container via SIGKILL.</p><p>Knowing this, the solution becomes obvious: we want php-fpm to be PID 1 as it knows how to handle it’s children. This happens when you specify the CMD using exec form as a shell is not created which leaves php-fpm as PID 1 and the SIGTERM is handled correctly.</p><p>This leads naturally on to another way to solve it: use the shell’s <code>exec</code> command:</p><pre lang="Dockerfile">
CMD exec /usr/sbin/php-fpm8.2 -F -R
</pre><p>This has the same effect as <code>bash exec</code> will replace the current shell with the command being executed.</p><p>Another solution is to run a real <code>init</code> process as PID 1. There are many options available out there.</p>]]></description>
      <link>https://akrabat.com/prevent-the-php-fpm-container-taking-10-seconds-to-stop/</link>
      <guid>https://akrabat.com/prevent-the-php-fpm-container-taking-10-seconds-to-stop/</guid>
      <pubDate>Tue, 03 Sep 2024 12:00:00 +0200</pubDate>
    </item>
    <item>
      <title><![CDATA[PHP 8.4.0 Beta 4 now available for testing - PHP: Hypertext Preprocessor]]></title>
      <description><![CDATA[<div><header class="title"><time datetime="2024-08-29T18:15:12+00:00">29 Aug 2024</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the release of PHP 8.4.0, Beta 4. This is the second beta release, continuing the PHP 8.4 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php84">PHP Wiki</a>.</p><p>For source downloads of PHP 8.4.0, Beta 4 please visit the <a href="https://downloads.php.net/~saki">download page</a>.</p><p>Please carefully test this version and report any issues found in the <a href="https://github.com/php/php-src/issues">bug reporting system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.4.0beta4/NEWS">NEWS</a> file or the <a href="https://github.com/php/php-src/blob/php-8.4.0beta4/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be Beta 5, planned for 12 September 2024.</p><p>The signatures for the release can be found in <a href="https://gist.github.com/SakiTakamachi/7132a67e0cdc1e792fa1e88f1726d5cc">the manifest</a> or on <a href="https://qa.php.net/">the QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></div><div><header class="title"><time datetime="2024-08-29T15:58:02+00:00">29 Aug 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.23. This is a bug fix release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.23 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.23">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-08-15T13:45:25+00:00">15 Aug 2024</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the release of PHP 8.4.0, Beta 3. This is the first beta release, continuing the PHP 8.4 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php84">PHP Wiki</a>.</p><p>For source downloads of PHP 8.4.0, Beta 3 please visit the <a href="https://downloads.php.net/~calvinb">download page</a>.</p><p>Please carefully test this version and report any issues found in the <a href="https://github.com/php/php-src/issues">bug reporting system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.4.0beta3/NEWS">NEWS</a> file or the <a href="https://github.com/php/php-src/blob/php-8.4.0beta3/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be Beta 4, planned for 29 August 2024.</p><p>The signatures for the release can be found in <a href="https://gist.github.com/NattyNarwhal/fdd2de9d3b165143d376679258811c15">the manifest</a> or on <a href="https://qa.php.net/">the QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></div><div><header class="title"><time datetime="2024-08-01T23:21:43+00:00">01 Aug 2024</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the second testing release of PHP 8.4.0, Alpha 4. This continues the PHP 8.4 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php84">PHP Wiki</a>.</p><p>For source downloads of PHP 8.4.0 Alpha 4 please visit the <a href="https://downloads.php.net/~saki/">download page</a>.</p><p>Please carefully test this version and report any issues found in the <a href="https://github.com/php/php-src/issues">bug reporting system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.4.0alpha4/NEWS">NEWS</a> file, or the <a href="https://github.com/php/php-src/blob/php-8.4.0alpha4/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be Beta 1, planned for 15 Aug 2024.</p><p>The signatures for the release can be found in <a href="https://gist.github.com/SakiTakamachi/6ef16057e96947aa030408db244718a7">the manifest</a> or on <a href="https://qa.php.net/">the QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></div><div><header class="title"><time datetime="2024-08-01T16:12:06+00:00">01 Aug 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.22. This is a bug fix release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.22 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.22">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-08-01T13:28:53+00:00">01 Aug 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.3.10. This is a bug fix release.</p><p>All PHP 8.3 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.3.10 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.3.10">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-07-18T13:30:46+00:00">18 Jul 2024</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the second testing release of PHP 8.4.0, Alpha 2. This continues the PHP 8.4 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php84">PHP Wiki</a>.</p><p>For source downloads of PHP 8.4.0 Alpha 2 please visit the <a href="https://downloads.php.net/~calvinb/">download page</a>.</p><p>Please carefully test this version and report any issues found in the <a href="https://github.com/php/php-src/issues">bug reporting system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.4.0alpha2/NEWS">NEWS</a> file, or the <a href="https://github.com/php/php-src/blob/php-8.4.0alpha2/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be Alpha 3, planned for 1 Aug 2024.</p><p>The signatures for the release can be found in <a href="https://gist.github.com/NattyNarwhal/74b55b8fcc6411ff8db05f87a6f41864">the manifest</a> or on <a href="https://qa.php.net/">the QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></div><div><header class="title"><time datetime="2024-07-05T13:22:12+00:00">05 Jul 2024</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the first testing release of PHP 8.4.0, Alpha 1. This starts the PHP 8.4 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php84">PHP Wiki</a>.</p><p>For source downloads of PHP 8.4.0 Alpha 1 please visit the <a href="https://downloads.php.net/~saki/">download page</a>.</p><p>Please carefully test this version and report any issues found using <a href="https://github.com/php/php-src/issues">the bug tracking system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.4.0alpha1/NEWS">NEWS</a> file, or the <a href="https://github.com/php/php-src/blob/php-8.4.0alpha1/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be Alpha 2, planned for 18 Jul 2024.</p><p>The signatures for the release can be found in the <a href="https://gist.github.com/SakiTakamachi/d3e32b780590319bee72d8402593a3ca">manifest</a> or on the <a href="https://qa.php.net/">QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></div><div><header class="title"><time datetime="2024-07-04T22:59:58+00:00">04 Jul 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.3.9. This is a bug fix release.</p><p>All PHP 8.3 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.3.9 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.3.9">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-07-04T14:43:24+00:00">04 Jul 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.21. This is a bug fix release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.21 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.21">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-06-06T14:56:47+00:00">06 Jun 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.20. This is a security release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.20 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.20">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-06-06T14:42:14+00:00">06 Jun 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.3.8. This is a security release.</p><p>All PHP 8.3 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.3.8 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.3.8">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-06-06T14:12:51+00:00">06 Jun 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.1.29. This is a security release.</p><p>All PHP 8.1 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.1.29 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.1.29">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-05-09T14:40:06+00:00">09 May 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.3.7. This is a bug fix release.</p><p>All PHP 8.3 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.3.7 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.3.7">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-05-09T13:48:33+00:00">09 May 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.19. This is a bug fix release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.19 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.19">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-04-24T18:40:29+00:00">24 Apr 2024</time>
</header><div class="newscontent"><p>EDIT 2024-04-25: Clarified when a PHP application is vulnerable to this bug.</p><p>Recently, a bug in <strong>glibc</strong> version 2.39 and older (<a href="https://nvd.nist.gov/vuln/detail/CVE-2024-2961">CVE-2024-2961</a>) was uncovered where a buffer overflow in character set conversions <strong>to</strong> the ISO-2022-CN-EXT character set can result in remote code execution.</p><p>This specific buffer overflow in glibc is exploitable through PHP, which exposes the iconv functionality of glibc to do character set conversions via the <a href="https://www.php.net/manual/en/function.iconv.php">iconv extension</a>. Although the bug is exploitable in the context of the PHP Engine, the bug is not in PHP. It is also not directly exploitable remotely.</p><p>The bug is exploitable, <strong>if and only if</strong>, the PHP application calls iconv <a href="https://www.php.net/manual/en/ref.iconv.php">functions</a> or <a href="https://www.php.net/manual/en/filters.convert.php#filters.convert.iconv">filters</a> with user-supplied character sets.</p><p>Applications are <strong>not</strong> vulnerable if:</p><ul><li>Glibc security updates from the distribution have been installed.</li>
<li>Or the iconv extension is not loaded.</li>
<li>Or the vulnerable character set has been removed from gconv-modules-extra.conf.</li>
<li>Or the application passes only specifically allowed character sets to iconv.</li>
</ul><p>Moreover, when using a user-supplied character set, it is good practice for applications to accept only specific charsets that have been explicitly allowed by the application. One example of how this can be done is by using an allow-list and the <a href="https://www.php.net/manual/en/function.array-search"><code>array_search()</code></a> function to check the encoding before passing it to iconv. For example: <code>array_search($charset, $allowed_list, true)</code></p><p>There are numerous reports online with titles like "Mitigating the iconv Vulnerability for PHP (CVE-2024-2961)" or "PHP Under Attack". These titles are misleading as this is <strong>not</strong> a bug in PHP itself.</p><p>If your PHP application is vulnerable, we first recommend to check if your Linux distribution has already published patched variants of glibc. <a href="https://security-tracker.debian.org/tracker/CVE-2024-2961">Debian</a>, CentOS, and others, have already done so, and please upgrade as soon as possible.</p><p>Once an update is available in glibc, updating that package on your Linux machine will be enough to alleviate the issue. You do not need to update PHP, as glibc is a dynamically linked library.</p><p>If your Linux distribution has not published a patched version of glibc, there is no fix for this issue. However, there exists a workaround described in <a href="https://rockylinux.org/news/glibc-vulnerability-april-2024/">GLIBC Vulnerability on Servers Serving PHP</a> which explains a way on how to remove the problematic character set from glibc. Perform this procedure for every gconv-modules-extra.conf file that is available on your system.</p><p>PHP users on Windows are not affected.</p><p>Therefore, a new version of PHP will not be released for this vulnerability.</p></div></div><div><header class="title"><time datetime="2024-04-12T15:42:40+00:00">12 Apr 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.1.28. This is a security release.</p><p>All PHP 8.1 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.1.28 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.1.28">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-04-11T14:34:04+00:00">11 Apr 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.3.6. This is a security release.</p><p>All PHP 8.3 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.3.6 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.3.6">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-04-11T13:37:51+00:00">11 Apr 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.18. This is a security release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.18 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.18">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-03-14T21:02:45+00:00">14 Mar 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.3.4. This is a bug fix release.</p><p>All PHP 8.3 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.3.4 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.3.4">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-03-14T15:21:29+00:00">14 Mar 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.17. This is a bug fix release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.17 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.17">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-02-15T13:36:20-05:00">15 Feb 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.16. This is a bug fix release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.16 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.16">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-02-15T15:48:46+00:00">15 Feb 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.3.3. This is a bug fix release.</p><p>All PHP 8.3 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.3.3 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.3.3">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-01-18T15:35:45+00:00">18 Jan 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.15. This is a bug fix release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.15 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.15">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-01-18T14:47:41+00:00">18 Jan 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.3.2. This is a bug fix release.</p><p>All PHP 8.3 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.3.2 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.3.2">ChangeLog</a>.</p></div></div>]]></description>
      <link>https://www.php.net/index.php#2024-08-29-2</link>
      <guid>https://www.php.net/index.php#2024-08-29-2</guid>
      <pubDate>Thu, 29 Aug 2024 02:00:00 +0200</pubDate>
    </item>
    <item>
      <title><![CDATA[Configuring PHP.INI settings in a PHP-FPM pool - Matthew Weier O'Phinney]]></title>
      <description><![CDATA[<p>I consume PHP via Docker primarily, and to keep it manageable, I generally use a PHP-FPM container, with a web server sitting in front of it. I learned something new about PHP configuration recently that (a) made my day, and (b) kept me humble, as I should have known this all along.</p><p>What was it? quite simply, the <code>php_admin_value</code> struct can be used to configure <code>php.ini</code> settings for the pool. This is a great alternative to <em>also</em> adding PHP configuration settings via <code>php.ini</code> (or an include file for <code>php.ini</code>), as it allows you to keep the settings specific to that pool. That way, if you <em>must</em> have multiple pools (e.g., to serve multiple applications from the same machine and/or same PHP version), you can still have separate configuration for each.</p><p>How does it work? In your pool configuration, add values to that struct:</p><pre class="language-ini hljs ini" data-lang="ini">php_admin_value[memory_limit] = 32M
php_admin_flag[error_reporting] = E_ALL &amp; ~E_NOTICE &amp; ~E_DEPRECATED
php_admin_flat[track_errors] = Off
; etc
</pre><p>With <a href="https://www.zend.com/products/zendphp-enterprise">ZendPHP</a>, we just launched some Ansible tooling, which operates on the assumption that you are deploying PHP-FPM — and as part of its operation, it creates a template for the FPM pool configuration, but not for the PHP SAPI. And this is fine! Because you can use the <code>php_admin_value</code> settings to configure the pool for the application you're deploying!</p><p>Looking forward to simplifying a few of my deployments with this!</p>]]></description>
      <link>https://mwop.net/blog/2024-08-27-til-php-fpm-admin-value.html</link>
      <guid>https://mwop.net/blog/2024-08-27-til-php-fpm-admin-value.html</guid>
      <pubDate>Wed, 28 Aug 2024 00:37:00 +0200</pubDate>
    </item>
    <item>
      <title><![CDATA[Pipelined database operations with python-oracledb 2.4 - Christopher Jones]]></title>
      <description><![CDATA[<div><div></div><p id="5913" class="pw-post-body-paragraph mg mh gu mi b mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd gn bk">Python-oracledb 2.4 introduces <a class="af ne" href="https://python-oracledb.readthedocs.io/en/latest/user_guide/asyncio.html#pipelining-database-operations" rel="noopener ugc nofollow" target="_blank">pipelining functionality</a> to improve the performance and scalability of your Python applications. Pipelining is simple in python-oracledb: you add operations such as INSERT and SELECT statements to a “pipeline” object, send that object to the database which processes the statements, and finally all the results will be returned to the application. Since the API is asynchronous, your application can submit the pipeline and continue with other local tasks while the database is doing its processing. This lets the database server and the application be kept busy, giving efficiencies and letting them work concurrently instead of waiting on each other for statements and results to be submitted/fetched.</p><figure class="ni nj nk nl nm nn nf ng paragraph-image"><div role="button" tabindex="0" class="no np fj nq bh nr"><div class="nf ng nh"><picture><source srcset="https://miro.medium.com/v2/resize:fit:640/format:webp/1*Zd5SIjh4PmFvvG-vEkciHA.png 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/1*Zd5SIjh4PmFvvG-vEkciHA.png 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/1*Zd5SIjh4PmFvvG-vEkciHA.png 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/1*Zd5SIjh4PmFvvG-vEkciHA.png 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/1*Zd5SIjh4PmFvvG-vEkciHA.png 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/1*Zd5SIjh4PmFvvG-vEkciHA.png 1100w, https://miro.medium.com/v2/resize:fit:1400/format:webp/1*Zd5SIjh4PmFvvG-vEkciHA.png 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" type="image/webp" /><source data-testid="og" srcset="https://miro.medium.com/v2/resize:fit:640/1*Zd5SIjh4PmFvvG-vEkciHA.png 640w, https://miro.medium.com/v2/resize:fit:720/1*Zd5SIjh4PmFvvG-vEkciHA.png 720w, https://miro.medium.com/v2/resize:fit:750/1*Zd5SIjh4PmFvvG-vEkciHA.png 750w, https://miro.medium.com/v2/resize:fit:786/1*Zd5SIjh4PmFvvG-vEkciHA.png 786w, https://miro.medium.com/v2/resize:fit:828/1*Zd5SIjh4PmFvvG-vEkciHA.png 828w, https://miro.medium.com/v2/resize:fit:1100/1*Zd5SIjh4PmFvvG-vEkciHA.png 1100w, https://miro.medium.com/v2/resize:fit:1400/1*Zd5SIjh4PmFvvG-vEkciHA.png 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" /></picture></div></div><figcaption class="nt ff nu nf ng nv nw bf b bg z du">Multiple SQL statements are sent in a single round-trip. Your application continues doing non-database work (i.e. do_local_stuff()) while the SQL statements are being executed. Results are returned from the database when it has executed all statements.</figcaption></figure><h1 id="dc94" class="nx ny gu bf nz oa ob oc od oe of og oh oi oj ok ol om on oo op oq or os ot ou bk">Pipelining Overview</h1><p id="6c68" class="pw-post-body-paragraph mg mh gu mi b mj ov ml mm mn ow mp mq mr ox mt mu mv oy mx my mz oz nb nc nd gn bk">Pipelining is useful when many small database operations need to be performed in rapid succession. It is supported by various drivers, including JDBC, Oracle Call Interface, ODP.NET, and Python.</p><p id="c1fa" class="pw-post-body-paragraph mg mh gu mi b mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd gn bk">The benefits of Oracle Database 23ai Pipelining:</p><ul class=""><li id="fed0" class="mg mh gu mi b mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd pa pb pc bk">Your app can do local work at the same time the database is processing statements.</li><li id="843b" class="mg mh gu mi b mj pd ml mm mn pe mp mq mr pf mt mu mv pg mx my mz ph nb nc nd pa pb pc bk">Your app doesn’t have to wait on one database response before sending a second statement.</li><li id="27d1" class="mg mh gu mi b mj pd ml mm mn pe mp mq mr pf mt mu mv pg mx my mz ph nb nc nd pa pb pc bk">Your app is kept busy.</li><li id="3042" class="mg mh gu mi b mj pd ml mm mn pe mp mq mr pf mt mu mv pg mx my mz ph nb nc nd pa pb pc bk">After the database finishes one statement, it doesn’t have to wait for your app to fetch results and send a second statement.</li><li id="a198" class="mg mh gu mi b mj pd ml mm mn pe mp mq mr pf mt mu mv pg mx my mz ph nb nc nd pa pb pc bk">The database is kept busy.</li><li id="96bf" class="mg mh gu mi b mj pd ml mm mn pe mp mq mr pf mt mu mv pg mx my mz ph nb nc nd pa pb pc bk">Fewer round-trips: reduced Oracle network listener wake-ups. Reduced interrupts. More efficient network usage.</li><li id="19c3" class="mg mh gu mi b mj pd ml mm mn pe mp mq mr pf mt mu mv pg mx my mz ph nb nc nd pa pb pc bk">Better overall system scalability.</li></ul><p id="5782" class="pw-post-body-paragraph mg mh gu mi b mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd gn bk">The reduction in round-trips is a significant contributor to pipelining’s performance improvement in comparison to executing the equivalent SQL statements individually. But, even with high-speed networks, where the performance benefit of pipelining may be lower, the database and network efficiencies of pipelining can still help system scalability.</p><p id="9779" class="pw-post-body-paragraph mg mh gu mi b mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd gn bk">Pipelining in Python is available via <a class="af ne" href="https://pypi.org/project/oracledb/" rel="noopener ugc nofollow" target="_blank">python-oracledb’s</a> Async classes: this means you must use the default Thin mode of python-oracledb, and use it in an asynchronous programming style. Pipelining works with Oracle Database 23ai. (Although you can actually use the new python-oracledb API when connected to older database versions, you won’t get the internal pipelining behavior and benefits — this is recommended only for migration or compatibility reasons). You can get Oracle Database 23ai from <a class="af ne" href="https://www.oracle.com/database/technologies/oracle-database-software-downloads.html" rel="noopener ugc nofollow" target="_blank">Oracle Database Software Downloads</a>.</p><p id="feaf" class="pw-post-body-paragraph mg mh gu mi b mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd gn bk">You can use the following python-oracledb calls to add operations to a pipeline:</p><ul class=""><li id="14ca" class="mg mh gu mi b mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd pa pb pc bk"><code class="cx pi pj pk pl b">add_callfunc()</code> - calling a stored PL/SQL function</li><li id="221d" class="mg mh gu mi b mj pd ml mm mn pe mp mq mr pf mt mu mv pg mx my mz ph nb nc nd pa pb pc bk"><code class="cx pi pj pk pl b">add_callproc()</code> - calling a stored PL/SQL procedure</li><li id="1267" class="mg mh gu mi b mj pd ml mm mn pe mp mq mr pf mt mu mv pg mx my mz ph nb nc nd pa pb pc bk"><code class="cx pi pj pk pl b">add_commit()</code> - commiting current transaction on the connection</li><li id="847b" class="mg mh gu mi b mj pd ml mm mn pe mp mq mr pf mt mu mv pg mx my mz ph nb nc nd pa pb pc bk"><code class="cx pi pj pk pl b">add_execute()</code> - executing one SQL statement</li><li id="f666" class="mg mh gu mi b mj pd ml mm mn pe mp mq mr pf mt mu mv pg mx my mz ph nb nc nd pa pb pc bk"><code class="cx pi pj pk pl b">add_executemany()</code> - executing one SQL statement with many bind values</li><li id="6209" class="mg mh gu mi b mj pd ml mm mn pe mp mq mr pf mt mu mv pg mx my mz ph nb nc nd pa pb pc bk"><code class="cx pi pj pk pl b">add_fetchall()</code> - executing a query and fetching all the results</li><li id="a0dd" class="mg mh gu mi b mj pd ml mm mn pe mp mq mr pf mt mu mv pg mx my mz ph nb nc nd pa pb pc bk"><code class="cx pi pj pk pl b">add_fetchmany()</code> - executing a query and fetching a set of the results</li><li id="1a82" class="mg mh gu mi b mj pd ml mm mn pe mp mq mr pf mt mu mv pg mx my mz ph nb nc nd pa pb pc bk"><code class="cx pi pj pk pl b">add_fetchone()</code> - executing a query and fetching one row</li></ul><p id="d740" class="pw-post-body-paragraph mg mh gu mi b mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd gn bk">Note the database processes the pipelined statements sequentially. The concurrency gain is betwen your application’s local work and the database doing its work.</p><p id="512a" class="pw-post-body-paragraph mg mh gu mi b mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd gn bk">Query results or OUT binds from one operation cannot be passed to subsequent operations in the same python-oracledb pipeline. If you need to use results from a pipeline operation in a subsequent database step, you can use multiple pipelines.</p><h1 id="64cb" class="nx ny gu bf nz oa ob oc od oe of og oh oi oj ok ol om on oo op oq or os ot ou bk">Social Network Example</h1><p id="afc6" class="pw-post-body-paragraph mg mh gu mi b mj ov ml mm mn ow mp mq mr ox mt mu mv oy mx my mz oz nb nc nd gn bk">An example use case is a social networking site. After you log in, your home page needs to show information gathered from various sources. It might show how many of your friends are also logged in. A news feed might show the top news items of the day. Current and forecast temperatures could be shown. Some of this data could be in a database, but require several distinct queries to fetch. Finding the current temperature might require Python calling out to a service to return that data. This is great use case for Pipelining: the distinct queries can be sent in a pipeline for processing, while the remote temperature sensor data is gathered at the same time.</p><p id="6aa9" class="pw-post-body-paragraph mg mh gu mi b mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd gn bk">The full code for this simple example web app is in <code class="cx pi pj pk pl b"><a class="af ne" href="https://gist.github.com/cjbj/9325e416d95d3203a57a308b27a13a90" rel="noopener ugc nofollow" target="_blank">pipeline-blog-quart.py</a></code>.</p><p id="86b9" class="pw-post-body-paragraph mg mh gu mi b mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd gn bk">The app needs to run asynchronously, so a framework that supports this is needed. I semi-arbitrarily chose the Quart micro-framework, which has a relationship to Flask. Flask’s async support isn’t complete enough for a full async application.</p><p id="3efc" class="pw-post-body-paragraph mg mh gu mi b mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd gn bk">The main body is:</p><pre class="ni nj nk nl nm pm pl pn bp po bb bk">app = Quart(__name__, )# Users home page<br />@app.route("/homepage")<br />async def homepage():<br />    r = await getdata() # Calls the database and remote temperature sensor<br />    return buildhtml(r) # Puts the data into an HTML page and returns it for display@app.before_serving<br />async def setup():<br />    start_pool()             # Start a pool of connections<br />    await create_schema()    # Create the demo tablesif __name__ == "__main__":<br />    print(f"Try loading http://127.0.0.1:{PORT}/homepage in a browser")<br />    app.run(port=PORT)</pre><p id="6778" class="pw-post-body-paragraph mg mh gu mi b mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd gn bk">I chose to show how a connection pool would be used, since connection pooling would be important for any actual multi-user app to do, and is something that is worth taking care to implement and configure correctly.</p><p id="4383" class="pw-post-body-paragraph mg mh gu mi b mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd gn bk">Then, for demo purposes, the app creates the schema and loads sample data when it starts. (This loading is itself another example use case for pipelining since multiple SQL statements are needed. See <code class="cx pi pj pk pl b">create_schema()</code> in the app).</p><p id="f353" class="pw-post-body-paragraph mg mh gu mi b mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd gn bk">Whenever the <code class="cx pi pj pk pl b">/homepage</code> URL is invoked, the <code class="cx pi pj pk pl b">getdata()</code> routine is called. This is where Pipelining really stars. The method does the database queries and accesses the temperature sensor concurrently. When all the data has been gathered, it is formatted into an HTML page by <code class="cx pi pj pk pl b">buildhtml()</code> which is then displayed by Quart. The <code class="cx pi pj pk pl b">getdata()</code> method and the external sensor method <code class="cx pi pj pk pl b">get_current_temperature()</code> look like:</p><pre class="ni nj nk nl nm pm pl pn bp po bb bk">async def get_current_temperature():<br />    return randint(0, 50) # fake what the thermometer returned - in Celsius of courseasync def getdata():<br />    global pool<br />    async with pool.acquire() as connection:# Create a pipeline and define the operations<br />        pipeline = oracledb.create_pipeline()<br />        pipeline.add_fetchone("select high from weather")<br />        pipeline.add_fetchall("select name from friends where active = true")<br />        pipeline.add_fetchall("select story from news order by popularity fetch next 5 rows only")# Run the pipeline and non-database operations concurrently<br />        current_temp, result_pl = await asyncio.gather(<br />            get_current_temperature(),<br />            connection.run_pipeline(pipeline)<br />        )# Extract the database pipeline query results<br />        t = result_pl[0].rows[0][0]          # max forecast temperature<br />        f = [n for n, in result_pl[1].rows]  # list of active friends<br />        n = [s for s, in result_pl[2].rows]  # top 5 news storiesreturn { "current": current_temp, "forecast": t, "friends": f, "news": n }</pre><p id="c68a" class="pw-post-body-paragraph mg mh gu mi b mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd gn bk">This creates a pipeline with three SELECT statements. By using <code class="cx pi pj pk pl b">asyncio.gather()</code>, the pipeline is executed in parallel with a call to <code class="cx pi pj pk pl b">get_current_temperature()</code> (which fakes reading an external thermometer). When all the data is available, it is returned in a dict.</p><p id="281b" class="pw-post-body-paragraph mg mh gu mi b mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd gn bk">Starting the app and loading the home page in a browser gives a page like:</p><figure class="ni nj nk nl nm nn nf ng paragraph-image"><div class="nf ng pu"><picture><source srcset="https://miro.medium.com/v2/resize:fit:640/format:webp/1*d-OsoO3-49S1wQi_J7sKbw.png 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/1*d-OsoO3-49S1wQi_J7sKbw.png 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/1*d-OsoO3-49S1wQi_J7sKbw.png 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/1*d-OsoO3-49S1wQi_J7sKbw.png 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/1*d-OsoO3-49S1wQi_J7sKbw.png 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/1*d-OsoO3-49S1wQi_J7sKbw.png 1100w, https://miro.medium.com/v2/resize:fit:738/format:webp/1*d-OsoO3-49S1wQi_J7sKbw.png 738w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 369px" type="image/webp" /><source data-testid="og" srcset="https://miro.medium.com/v2/resize:fit:640/1*d-OsoO3-49S1wQi_J7sKbw.png 640w, https://miro.medium.com/v2/resize:fit:720/1*d-OsoO3-49S1wQi_J7sKbw.png 720w, https://miro.medium.com/v2/resize:fit:750/1*d-OsoO3-49S1wQi_J7sKbw.png 750w, https://miro.medium.com/v2/resize:fit:786/1*d-OsoO3-49S1wQi_J7sKbw.png 786w, https://miro.medium.com/v2/resize:fit:828/1*d-OsoO3-49S1wQi_J7sKbw.png 828w, https://miro.medium.com/v2/resize:fit:1100/1*d-OsoO3-49S1wQi_J7sKbw.png 1100w, https://miro.medium.com/v2/resize:fit:738/1*d-OsoO3-49S1wQi_J7sKbw.png 738w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 369px" /></picture></div></figure><p id="9fa1" class="pw-post-body-paragraph mg mh gu mi b mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd gn bk">The reading of the thermometer and the database work are executed concurrently: both the app and the database are kept busy. The application response time is reduced, making users happier. When the database is doing its work, it is kept busy with fewer interrupts and pauses, making it more efficient. Overall system scalability has improved.</p><h1 id="c55e" class="nx ny gu bf nz oa ob oc od oe of og oh oi oj ok ol om on oo op oq or os ot ou bk">Performance Example</h1><p id="f4a4" class="pw-post-body-paragraph mg mh gu mi b mj ov ml mm mn ow mp mq mr ox mt mu mv oy mx my mz oz nb nc nd gn bk">An example pipeline with more operations makes it easier to see performance benefits.</p><p id="9162" class="pw-post-body-paragraph mg mh gu mi b mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd gn bk">Let’s start with a program that doesn’t use Pipelining (see <code class="cx pi pj pk pl b"><a class="af ne" href="https://gist.github.com/cjbj/6abe7e67078bfa23a0b573d733b587b0" rel="noopener ugc nofollow" target="_blank">pipeline-bm-non.py</a></code>). It uses the existing async functionality of python-oracledb but every statement is executed sequentially:</p><pre class="ni nj nk nl nm pm pl pn bp po bb bk"># No Pipeliningfor i in range(50):<br />    await connection.execute("insert into TestTempTable values (:1, :2)", [i + 1, f"Value {i + 1}"])await connection.execute("""<br />    update TestTempTable set Description = Description || ' (modified)'<br />    where mod(ID, 2) = 1""")for i in range(50):<br />    await connection.execute("insert into TestTempTable values (:1, :2)", [i + 51, f"Value {i + 51}"])await connection.commit()rows = await connection.fetchall("select * from TestTempTable")</pre><p id="8595" class="pw-post-body-paragraph mg mh gu mi b mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd gn bk">Note the demo executes lots of the same INSERT statement. This is simply to showcase a “larger” pipeline length. In production non-pipelining and pipelining code, you should use <code class="cx pi pj pk pl b">executemany()</code> for such a flow.</p><p id="6d82" class="pw-post-body-paragraph mg mh gu mi b mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd gn bk">But, putting aside that comment, each of the statements executed will require a round-trip.</p><p id="ac42" class="pw-post-body-paragraph mg mh gu mi b mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd gn bk">To cut down the number of round-trips, the script can be converted to use Pipelining (see <code class="cx pi pj pk pl b"><a class="af ne" href="https://gist.github.com/cjbj/50d758ee5b6d507a47222d079619238a" rel="noopener ugc nofollow" target="_blank">pipeline-bm.py</a></code>):</p><pre class="ni nj nk nl nm pm pl pn bp po bb bk"># Pipelining with Oracle Database 23aipipeline = oracledb.create_pipeline()for i in range(50):<br />    pipeline.add_execute("insert into TestTempTable values (:1, :2)", [i + 1, f"Value {i + 1}"])pipeline.add_execute("""<br />    update TestTempTable set<br />        Description = Description || ' (modified)'<br />    where mod(ID, 2) = 1""")for i in range(50):<br />    pipeline.add_execute("insert into TestTempTable values (:1, :2)", [i + 51, f"Value {i + 51}"])pipeline.add_commit()pipeline.add_fetchall("select * from TestTempTable")result = await connection.run_pipeline(pipeline)</pre><p id="9cc5" class="pw-post-body-paragraph mg mh gu mi b mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd gn bk">This will require only one round-trip, initiated when <code class="cx pi pj pk pl b">run_pipeline()</code> is called.</p><p id="6f03" class="pw-post-body-paragraph mg mh gu mi b mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd gn bk">On my laptop, with the database running locally in an emulated container environment, typical end-to-end timing results I saw were:</p><pre class="ni nj nk nl nm pm pl pn bp po bb bk">$ python3 pipeline-bm.py; python3 pipeline-bm-non.py<br />pipelining:    0.34 seconds<br />no pipelining: 0.46 seconds</pre><p id="1212" class="pw-post-body-paragraph mg mh gu mi b mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd gn bk">This particular result is a 26% decrease in end-to-end time for the application’s database workload. Your results will vary. The Pipelined application was much more efficient. I could also have utilized parallelism to allow the app to continue other work while the database was processing statements (as shown in the social networking example), giving further gains to overall app performance.</p><h1 id="32d9" class="nx ny gu bf nz oa ob oc od oe of og oh oi oj ok ol om on oo op oq or os ot ou bk">Conclusion</h1><p id="cf5a" class="pw-post-body-paragraph mg mh gu mi b mj ov ml mm mn ow mp mq mr ox mt mu mv oy mx my mz oz nb nc nd gn bk">Pipelining in Oracle Database 23ai is a technique to improve application performance and system scalability by keeping the database busy while allowing applications to concurrently continue local work. Pipelining is available to applications using python-oracledb, JDBC, ODP.Net and Oracle Call Interface.</p><p id="aa00" class="pw-post-body-paragraph mg mh gu mi b mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd gn bk">Pipelining is useful when many small database operations need to be performed in rapid succession. It is most effective when networks costs are high. But even on fast networks, or with a small number of operations, pipelining provides system benefits.</p><p id="4789" class="pw-post-body-paragraph mg mh gu mi b mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd gn bk">The new Pipeline support in python-oracledb 2.4 builds on the existing support for asyncio. It is available in Thin mode via new Pipeline classes. In this release it is marked ‘experimental’ to give you time to test and suggest small or big changes before we finalize the API. We have tested with asyncio. Your feedback about the behavior with other alternatives like uvloop would be invaluable.</p><h1 id="75a9" class="nx ny gu bf nz oa ob oc od oe of og oh oi oj ok ol om on oo op oq or os ot ou bk">Pipelining References</h1><ul class=""><li id="f97a" class="mg mh gu mi b mj ov ml mm mn ow mp mq mr ox mt mu mv oy mx my mz oz nb nc nd pa pb pc bk">Python-oracledb documentation: <a class="af ne" href="https://python-oracledb.readthedocs.io/en/latest/user_guide/asyncio.html#pipelining" rel="noopener ugc nofollow" target="_blank">Pipelining Database Operations</a></li><li id="8ad6" class="mg mh gu mi b mj pd ml mm mn pe mp mq mr pf mt mu mv pg mx my mz ph nb nc nd pa pb pc bk">Blog: <a class="af ne" href="https://medium.com/@veronica.dumitriu/introducing-pipelining-and-asynch-programming-for-oracle-database-23c-2ec67fa7d2af" rel="noopener">Introducing Pipelining and Asynch Programming for Oracle Database 23ai</a></li><li id="f5d9" class="mg mh gu mi b mj pd ml mm mn pe mp mq mr pf mt mu mv pg mx my mz ph nb nc nd pa pb pc bk">Oracle Call Interface documentation: <a class="af ne" href="https://docs.oracle.com/en/database/oracle/oracle-database/23/lnoci/oci-pipelining.html#GUID-D131842B-354E-431D-A1B3-26A001289806" rel="noopener ugc nofollow" target="_blank">OCI Pipelining</a></li><li id="99c0" class="mg mh gu mi b mj pd ml mm mn pe mp mq mr pf mt mu mv pg mx my mz ph nb nc nd pa pb pc bk">Blog: <a class="af ne" href="https://kuassimensah.medium.com/whats-in-oracle-db-23c-free-developer-release-for-java-developers-26931081682c" rel="noopener">What’s in ‘Oracle DB 23c Free Developer Release’ for Java Developers</a></li><li id="f4f6" class="mg mh gu mi b mj pd ml mm mn pe mp mq mr pf mt mu mv pg mx my mz ph nb nc nd pa pb pc bk">JDBC Documentation: <a class="af ne" href="https://docs.oracle.com/en/database/oracle/oracle-database/23/jjdbc/pipelined-database-operations.html" rel="noopener ugc nofollow" target="_blank">Support for Pipelined Database Operations</a></li><li id="47a1" class="mg mh gu mi b mj pd ml mm mn pe mp mq mr pf mt mu mv pg mx my mz ph nb nc nd pa pb pc bk">Blog: <a class="af ne" href="https://medium.com/@alex.keh/asynchronous-odp-net-and-pipelining-improve-performance-by-reducing-latency-f7314a6970be" rel="noopener">Asynchronous ODP.NET and Pipelining: Improve Performance by Reducing Latency</a></li></ul><h1 id="70d1" class="nx ny gu bf nz oa ob oc od oe of og oh oi oj ok ol om on oo op oq or os ot ou bk">Installing or Upgrading python-oracledb</h1><p id="1573" class="pw-post-body-paragraph mg mh gu mi b mj ov ml mm mn ow mp mq mr ox mt mu mv oy mx my mz oz nb nc nd gn bk">You can install or upgrade python-oracledb by running:</p><pre class="ni nj nk nl nm pm pl pn bp po bb bk">python -m pip install oracledb --upgrade</pre><p id="356b" class="pw-post-body-paragraph mg mh gu mi b mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd gn bk">The <code class="cx pi pj pk pl b">pip</code> options <code class="cx pi pj pk pl b">--proxy</code> and <code class="cx pi pj pk pl b">--user</code> may be useful in some environments. See <a class="af ne" href="https://python-oracledb.readthedocs.io/en/latest/user_guide/installation.html" rel="noopener ugc nofollow" target="_blank">python-oracledb Installation</a> for details.</p><h1 id="3750" class="nx ny gu bf nz oa ob oc od oe of og oh oi oj ok ol om on oo op oq or os ot ou bk">Python-oracledb References</h1><p id="a1b1" class="pw-post-body-paragraph mg mh gu mi b mj ov ml mm mn ow mp mq mr ox mt mu mv oy mx my mz oz nb nc nd gn bk">Home page: <a class="af ne" href="https://oracle.github.io/python-oracledb/index.html" rel="noopener ugc nofollow" target="_blank">oracle.github.io/python-oracledb/index.html</a></p><p id="e8db" class="pw-post-body-paragraph mg mh gu mi b mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd gn bk">Installation instructions: <a class="af ne" href="https://python-oracledb.readthedocs.io/en/latest/user_guide/installation.html" rel="noopener ugc nofollow" target="_blank">python-oracledb.readthedocs.io/en/latest/installation.html</a></p><p id="402f" class="pw-post-body-paragraph mg mh gu mi b mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd gn bk">Documentation: <a class="af ne" href="https://python-oracledb.readthedocs.io/en/latest/index.html" rel="noopener ugc nofollow" target="_blank">python-oracledb.readthedocs.io/en/latest/index.html</a></p><p id="b655" class="pw-post-body-paragraph mg mh gu mi b mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd gn bk">Release Notes: <a class="af ne" href="https://python-oracledb.readthedocs.io/en/latest/release_notes.html" rel="noopener ugc nofollow" target="_blank">python-oracledb.readthedocs.io/en/latest/release_notes.html</a></p><p id="5a24" class="pw-post-body-paragraph mg mh gu mi b mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd gn bk">Discussions: <a class="af ne" href="https://github.com/oracle/python-oracledb/discussions" rel="noopener ugc nofollow" target="_blank">github.com/oracle/python-oracledb/discussions</a></p><p id="d72e" class="pw-post-body-paragraph mg mh gu mi b mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd gn bk">Issues: <a class="af ne" href="https://github.com/oracle/python-oracledb/issues" rel="noopener ugc nofollow" target="_blank">github.com/oracle/python-oracledb/issues</a></p><p id="31ac" class="pw-post-body-paragraph mg mh gu mi b mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd gn bk">Source Code Repository: <a class="af ne" href="https://github.com/oracle/python-oracledb" rel="noopener ugc nofollow" target="_blank">github.com/oracle/python-oracledb</a></p></div>]]></description>
      <link>https://medium.com/oracledevs/pipelined-database-operations-with-python-oracledb-2-4-dd8bfbdadf0d?source=rss-adc937c3a9d------2</link>
      <guid>https://medium.com/oracledevs/pipelined-database-operations-with-python-oracledb-2-4-dd8bfbdadf0d?source=rss-adc937c3a9d------2</guid>
      <pubDate>Wed, 21 Aug 2024 00:08:00 +0200</pubDate>
    </item>
    <item>
      <title><![CDATA[Python-oracledb 2.4 has been released - Christopher Jones]]></title>
      <description><![CDATA[<div><div></div><p id="bf8e" class="pw-post-body-paragraph mg mh gu mi b mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd gn bk"><a class="af ne" href="https://oracle.github.io/python-oracledb/index.html" rel="noopener ugc nofollow" target="_blank"><strong class="mi gv">Python-oracledb 2.4</strong></a><strong class="mi gv">, the extremely popular Oracle Database interface for Python, is now on </strong><a class="af ne" href="https://pypi.python.org/pypi/oracledb/" rel="noopener ugc nofollow" target="_blank"><strong class="mi gv">PyPI</strong></a><strong class="mi gv">.</strong></p><figure class="ni nj nk nl nm nn nf ng paragraph-image"><div role="button" tabindex="0" class="no np fj nq bh nr"><div class="nf ng nh"><picture><source srcset="https://miro.medium.com/v2/resize:fit:640/format:webp/0*1CB_SABymYybTOeo 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/0*1CB_SABymYybTOeo 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/0*1CB_SABymYybTOeo 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/0*1CB_SABymYybTOeo 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/0*1CB_SABymYybTOeo 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/0*1CB_SABymYybTOeo 1100w, https://miro.medium.com/v2/resize:fit:1400/format:webp/0*1CB_SABymYybTOeo 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" type="image/webp" /><source data-testid="og" srcset="https://miro.medium.com/v2/resize:fit:640/0*1CB_SABymYybTOeo 640w, https://miro.medium.com/v2/resize:fit:720/0*1CB_SABymYybTOeo 720w, https://miro.medium.com/v2/resize:fit:750/0*1CB_SABymYybTOeo 750w, https://miro.medium.com/v2/resize:fit:786/0*1CB_SABymYybTOeo 786w, https://miro.medium.com/v2/resize:fit:828/0*1CB_SABymYybTOeo 828w, https://miro.medium.com/v2/resize:fit:1100/0*1CB_SABymYybTOeo 1100w, https://miro.medium.com/v2/resize:fit:1400/0*1CB_SABymYybTOeo 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" /></picture></div></div><figcaption class="nt ff nu nf ng nv nw bf b bg z du">Photo by <a class="af ne" href="https://unsplash.com/@kazuend?utm_source=medium&amp;utm_medium=referral" rel="noopener ugc nofollow" target="_blank">kazuend</a> on <a class="af ne" href="https://unsplash.com/?utm_source=medium&amp;utm_medium=referral" rel="noopener ugc nofollow" target="_blank">Unsplash</a></figcaption></figure><p id="8514" class="pw-post-body-paragraph mg mh gu mi b mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd gn bk">Python-oracledb is an open source package for the Python Database API specification with many additions to support advanced Oracle Database features. By default, it is a ‘Thin’ driver that is immediately usable without needing any additional install e.g. no Instant Client is required. Python-oracledb is the new name for the cx_Oracle driver.</p><p id="8027" class="pw-post-body-paragraph mg mh gu mi b mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd gn bk">To get started quickly, use <a class="af ne" href="https://github.com/oracle/python-oracledb/tree/main/samples/sample_container" rel="noopener ugc nofollow" target="_blank">samples/sample_container</a> to create a container image containing Oracle Database and python-oracledb.</p><h1 id="a54b" class="nx ny gu bf nz oa ob oc od oe of og oh oi oj ok ol om on oo op oq or os ot ou bk">Top Features in python-oracledb 2.4</h1><ul class=""><li id="b196" class="mg mh gu mi b mj ov ml mm mn ow mp mq mr ox mt mu mv oy mx my mz oz nb nc nd pa pb pc bk">Support for Oracle Database 23ai Pipelining. This is a great feature. For details, see my companion blog post <a class="af ne" rel="noopener" href="https://cjones-oracle.medium.com/pipelined-database-operations-with-python-oracledb-2-4-dd8bfbdadf0d">Pipelined database operations with python-oracledb 2.4</a>.</li><li id="3364" class="mg mh gu mi b mj pd ml mm mn pe mp mq mr pf mt mu mv pg mx my mz ph nb nc nd pa pb pc bk">A refactored connection string parser to improve support for various connection string syntaxes.</li><li id="f4e1" class="mg mh gu mi b mj pd ml mm mn pe mp mq mr pf mt mu mv pg mx my mz ph nb nc nd pa pb pc bk">Added packages for Python 3.13 and dropped support for Python 3.7.</li></ul><p id="77e6" class="pw-post-body-paragraph mg mh gu mi b mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd gn bk">Other enhancements and bug fixes also landed. Check out the <a class="af ne" href="https://python-oracledb.readthedocs.io/en/latest/release_notes.html#releasenotes" rel="noopener ugc nofollow" target="_blank">release notes</a> for details.</p><h1 id="596e" class="nx ny gu bf nz oa ob oc od oe of og oh oi oj ok ol om on oo op oq or os ot ou bk">Installing or Upgrading python-oracledb</h1><p class="pw-post-body-paragraph mg mh gu mi b mj ov ml mm mn ow mp mq mr ox mt mu mv oy mx my mz oz nb nc nd gn bk">You can install or upgrade python-oracledb by running:</p><pre class="ni nj nk nl nm pi pj pk bp pl bb bk">python -m pip install oracledb --upgrade</pre><p class="pw-post-body-paragraph mg mh gu mi b mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd gn bk">The <code class="cx pr ps pt pj b">pip</code> options <code class="cx pr ps pt pj b">--proxy</code> and <code class="cx pr ps pt pj b">--user</code> may be useful in some environments. See <a class="af ne" href="https://python-oracledb.readthedocs.io/en/latest/user_guide/installation.html" rel="noopener ugc nofollow" target="_blank">python-oracledb Installation</a> for details.</p><h1 class="nx ny gu bf nz oa ob oc od oe of og oh oi oj ok ol om on oo op oq or os ot ou bk">Python-oracledb References</h1><p class="pw-post-body-paragraph mg mh gu mi b mj ov ml mm mn ow mp mq mr ox mt mu mv oy mx my mz oz nb nc nd gn bk">Home page: <a class="af ne" href="https://oracle.github.io/python-oracledb/index.html" rel="noopener ugc nofollow" target="_blank">oracle.github.io/python-oracledb/index.html</a></p><p class="pw-post-body-paragraph mg mh gu mi b mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd gn bk">Installation instructions: <a class="af ne" href="https://python-oracledb.readthedocs.io/en/latest/user_guide/installation.html" rel="noopener ugc nofollow" target="_blank">python-oracledb.readthedocs.io/en/latest/installation.html</a></p><p class="pw-post-body-paragraph mg mh gu mi b mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd gn bk">Documentation: <a class="af ne" href="https://python-oracledb.readthedocs.io/en/latest/index.html" rel="noopener ugc nofollow" target="_blank">python-oracledb.readthedocs.io/en/latest/index.html</a></p><p class="pw-post-body-paragraph mg mh gu mi b mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd gn bk">Release Notes: <a class="af ne" href="https://python-oracledb.readthedocs.io/en/latest/release_notes.html" rel="noopener ugc nofollow" target="_blank">python-oracledb.readthedocs.io/en/latest/release_notes.html</a></p><p class="pw-post-body-paragraph mg mh gu mi b mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd gn bk">Discussions: <a class="af ne" href="https://github.com/oracle/python-oracledb/discussions" rel="noopener ugc nofollow" target="_blank">github.com/oracle/python-oracledb/discussions</a></p><p class="pw-post-body-paragraph mg mh gu mi b mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd gn bk">Issues: <a class="af ne" href="https://github.com/oracle/python-oracledb/issues" rel="noopener ugc nofollow" target="_blank">github.com/oracle/python-oracledb/issues</a></p><p class="pw-post-body-paragraph mg mh gu mi b mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd gn bk">Source Code Repository: <a class="af ne" href="https://github.com/oracle/python-oracledb" rel="noopener ugc nofollow" target="_blank">github.com/oracle/python-oracledb</a></p></div>]]></description>
      <link>https://cjones-oracle.medium.com/python-oracledb-2-4-has-been-released-46041e38046f?source=rss-adc937c3a9d------2</link>
      <guid>https://cjones-oracle.medium.com/python-oracledb-2-4-has-been-released-46041e38046f?source=rss-adc937c3a9d------2</guid>
      <pubDate>Wed, 21 Aug 2024 00:07:00 +0200</pubDate>
    </item>
    <item>
      <title><![CDATA[Query result caching for fast database applications - Christopher Jones]]></title>
      <description><![CDATA[<div><div></div><p id="b43d" class="pw-post-body-paragraph mh mi gv mj b mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne go bj">Oracle Database’s built-in “Client Result Cache” is an efficient, integrated, managed cache that can dramatically improve query performance and significantly reduce database load when repeatedly querying mostly-static tables, such as postal codes or part numbers. No application changes are needed. No separate mid-tier cache needs to be installed. CRC is available to any “Thick” client that uses Oracle Client libraries, such as drivers for Python, Node.js, Go, PHP, Rust, Ruby, and Oracle’s C API. It is also available in JDBC. This blog post demos an example in Python.</p><figure class="ni nj nk nl nm nn nf ng paragraph-image"><div role="button" tabindex="0" class="no np fk nq bg nr"><div class="nf ng nh"><picture><source srcset="https://miro.medium.com/v2/resize:fit:640/format:webp/0*ZIOK2dbqQMtHPS-H 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/0*ZIOK2dbqQMtHPS-H 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/0*ZIOK2dbqQMtHPS-H 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/0*ZIOK2dbqQMtHPS-H 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/0*ZIOK2dbqQMtHPS-H 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/0*ZIOK2dbqQMtHPS-H 1100w, https://miro.medium.com/v2/resize:fit:1400/format:webp/0*ZIOK2dbqQMtHPS-H 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" type="image/webp" /><source data-testid="og" srcset="https://miro.medium.com/v2/resize:fit:640/0*ZIOK2dbqQMtHPS-H 640w, https://miro.medium.com/v2/resize:fit:720/0*ZIOK2dbqQMtHPS-H 720w, https://miro.medium.com/v2/resize:fit:750/0*ZIOK2dbqQMtHPS-H 750w, https://miro.medium.com/v2/resize:fit:786/0*ZIOK2dbqQMtHPS-H 786w, https://miro.medium.com/v2/resize:fit:828/0*ZIOK2dbqQMtHPS-H 828w, https://miro.medium.com/v2/resize:fit:1100/0*ZIOK2dbqQMtHPS-H 1100w, https://miro.medium.com/v2/resize:fit:1400/0*ZIOK2dbqQMtHPS-H 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" /></picture></div></div><figcaption class="nt fe nu nf ng nv nw be b bf z dt">CRC unlocks performance (Photo by <a class="af nx" href="https://unsplash.com/@schluesseldienstvergleich_eu?utm_source=medium&amp;utm_medium=referral" rel="noopener ugc nofollow" target="_blank">Maria Ziegler</a> on <a class="af nx" href="https://unsplash.com/?utm_source=medium&amp;utm_medium=referral" rel="noopener ugc nofollow" target="_blank">Unsplash</a>)</figcaption></figure><h1 id="e9ee" class="ny nz gv be oa ob oc od oe of og oh oi oj ok ol om on oo op oq or os ot ou ov bj">Benefits of Client Result Caching</h1><ul class=""><li id="8778" class="mh mi gv mj b mk ow mm mn mo ox mq mr ms oy mu mv mw oz my mz na pa nc nd ne pb pc pd bj">Can be used without needing to modify application code</li><li id="592f" class="mh mi gv mj b mk pe mm mn mo pf mq mr ms pg mu mv mw ph my mz na pi nc nd ne pb pc pd bj">Improved query response time</li><li id="df62" class="mh mi gv mj b mk pe mm mn mo pf mq mr ms pg mu mv mw ph my mz na pi nc nd ne pb pc pd bj">Statements are not sent to the database to be executed</li><li id="55ba" class="mh mi gv mj b mk pe mm mn mo pf mq mr ms pg mu mv mw ph my mz na pi nc nd ne pb pc pd bj">Better performance by eliminating server round-trips</li><li id="e7fa" class="mh mi gv mj b mk pe mm mn mo pf mq mr ms pg mu mv mw ph my mz na pi nc nd ne pb pc pd bj">Improved database server scalability by saving server resources</li><li id="023b" class="mh mi gv mj b mk pe mm mn mo pf mq mr ms pg mu mv mw ph my mz na pi nc nd ne pb pc pd bj">Automatically managed cache invalidation, keeping the cache consistent with database changes</li><li id="ae23" class="mh mi gv mj b mk pe mm mn mo pf mq mr ms pg mu mv mw ph my mz na pi nc nd ne pb pc pd bj">No mid-tier cache server required</li><li id="d04d" class="mh mi gv mj b mk pe mm mn mo pf mq mr ms pg mu mv mw ph my mz na pi nc nd ne pb pc pd bj">Developers don’t need to build, or use, a custom cache</li></ul><h1 id="251a" class="ny nz gv be oa ob oc od oe of og oh oi oj ok ol om on oo op oq or os ot ou ov bj">What is Client Result Caching?</h1><p id="d5e3" class="pw-post-body-paragraph mh mi gv mj b mk ow mm mn mo ox mq mr ms oy mu mv mw oz my mz na pa nc nd ne go bj">The <a class="af nx" href="https://www.oracle.com/pls/topic/lookup?ctx=dblatest&amp;id=GUID-35CB2592-7588-4C2D-9075-6F639F25425E" rel="noopener ugc nofollow" target="_blank">Client Result Cache</a> (CRC) is a memory area inside a client process (i.e. the application process) that caches SELECT query results. Its presence is invisible to application code, which just executes queries and gets results as normal. The cache is internal to the Oracle client libraries used by the application. The client libraries know whether a query’s result set is already cached. If so, the SELECT statement gets the results from the cache immediately without involving the database. If the results aren’t in the cache, then the SELECT is sent to the database for execution — which has obvious network and database costs, and contributes to overall system load. Magically the client libraries know whether the cache is outdated and needs to be refreshed. This makes CRC very attractive because application logic doesn’t need to be changed to give performance benefits.</p><figure class="ni nj nk nl nm nn nf ng paragraph-image"><div class="nf ng pj"><picture><source srcset="https://miro.medium.com/v2/resize:fit:640/format:webp/1*nCRPOjWWxbjHOf6JRJNc5w.gif 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/1*nCRPOjWWxbjHOf6JRJNc5w.gif 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/1*nCRPOjWWxbjHOf6JRJNc5w.gif 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/1*nCRPOjWWxbjHOf6JRJNc5w.gif 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/1*nCRPOjWWxbjHOf6JRJNc5w.gif 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/1*nCRPOjWWxbjHOf6JRJNc5w.gif 1100w, https://miro.medium.com/v2/resize:fit:1216/format:webp/1*nCRPOjWWxbjHOf6JRJNc5w.gif 1216w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 608px" type="image/webp" /><source data-testid="og" srcset="https://miro.medium.com/v2/resize:fit:640/1*nCRPOjWWxbjHOf6JRJNc5w.gif 640w, https://miro.medium.com/v2/resize:fit:720/1*nCRPOjWWxbjHOf6JRJNc5w.gif 720w, https://miro.medium.com/v2/resize:fit:750/1*nCRPOjWWxbjHOf6JRJNc5w.gif 750w, https://miro.medium.com/v2/resize:fit:786/1*nCRPOjWWxbjHOf6JRJNc5w.gif 786w, https://miro.medium.com/v2/resize:fit:828/1*nCRPOjWWxbjHOf6JRJNc5w.gif 828w, https://miro.medium.com/v2/resize:fit:1100/1*nCRPOjWWxbjHOf6JRJNc5w.gif 1100w, https://miro.medium.com/v2/resize:fit:1216/1*nCRPOjWWxbjHOf6JRJNc5w.gif 1216w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 608px" /></picture></div><figcaption class="nt fe nu nf ng nv nw be b bf z dt">Connections in the process share the Client Result Cache</figcaption></figure><p id="ff47" class="pw-post-body-paragraph mh mi gv mj b mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne go bj">Oracle Database has supported CRC for many versions. When we first released it back in the Oracle Database 11g timeframe, we ran the ‘Niles benchmark’ and saw these material improvements:</p><figure class="ni nj nk nl nm nn nf ng paragraph-image"><div role="button" tabindex="0" class="no np fk nq bg nr"><div class="nf ng pk"><picture><source srcset="https://miro.medium.com/v2/resize:fit:640/format:webp/1*opHGVhsyJ3ZcsGNzetCGlQ.png 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/1*opHGVhsyJ3ZcsGNzetCGlQ.png 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/1*opHGVhsyJ3ZcsGNzetCGlQ.png 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/1*opHGVhsyJ3ZcsGNzetCGlQ.png 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/1*opHGVhsyJ3ZcsGNzetCGlQ.png 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/1*opHGVhsyJ3ZcsGNzetCGlQ.png 1100w, https://miro.medium.com/v2/resize:fit:1400/format:webp/1*opHGVhsyJ3ZcsGNzetCGlQ.png 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" type="image/webp" /><source data-testid="og" srcset="https://miro.medium.com/v2/resize:fit:640/1*opHGVhsyJ3ZcsGNzetCGlQ.png 640w, https://miro.medium.com/v2/resize:fit:720/1*opHGVhsyJ3ZcsGNzetCGlQ.png 720w, https://miro.medium.com/v2/resize:fit:750/1*opHGVhsyJ3ZcsGNzetCGlQ.png 750w, https://miro.medium.com/v2/resize:fit:786/1*opHGVhsyJ3ZcsGNzetCGlQ.png 786w, https://miro.medium.com/v2/resize:fit:828/1*opHGVhsyJ3ZcsGNzetCGlQ.png 828w, https://miro.medium.com/v2/resize:fit:1100/1*opHGVhsyJ3ZcsGNzetCGlQ.png 1100w, https://miro.medium.com/v2/resize:fit:1400/1*opHGVhsyJ3ZcsGNzetCGlQ.png 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" /></picture></div></div><figcaption class="nt fe nu nf ng nv nw be b bf z dt">Benefits of Oracle Database Client Result Caching in the Niles benchmark</figcaption></figure><h1 id="c427" class="ny nz gv be oa ob oc od oe of og oh oi oj ok ol om on oo op oq or os ot ou ov bj">How does Client Result Caching work?</h1><p id="cfc7" class="pw-post-body-paragraph mh mi gv mj b mk ow mm mn mo ox mq mr ms oy mu mv mw oz my mz na pa nc nd ne go bj">Oracle Client libraries manage a result cache for each client process. It is shared by all sessions (i.e. connections) inside that process. The cache can be enabled, and its size specified, with a database initialization parameter.</p><p id="4d64" class="pw-post-body-paragraph mh mi gv mj b mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne go bj">Client result caching stores the results of the outermost query, which are the columns defined by application.</p><p id="c7f0" class="pw-post-body-paragraph mh mi gv mj b mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne go bj">Oracle Database transparently keeps the client result cache consistent with session state or database changes that affect it. When any database transaction changes the data or metadata of database objects used to build the cached result, the database sends an invalidation flag to the client as part of its response to the application’s next round-trip. (A round-trip is defined as the travel of a message from the application to the database and back. Calling each driver function, or accessing a driver attribute, will require zero or more round-trips.)</p><p id="5a37" class="pw-post-body-paragraph mh mi gv mj b mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne go bj">If the application is idle and hasn’t initiated a round-trip to the database in a certain amount of time, then cached values are assumed to be invalid. This invalidation time is configurable.</p><p id="4d57" class="pw-post-body-paragraph mh mi gv mj b mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne go bj">Oracle recommends using CRC for queries from small, read-only or read-mostly tables, however some customers have used it for relatively large tables.</p><h1 id="d864" class="ny nz gv be oa ob oc od oe of og oh oi oj ok ol om on oo op oq or os ot ou ov bj">Enabling Client Result Caching in Oracle Database</h1><p id="22de" class="pw-post-body-paragraph mh mi gv mj b mk ow mm mn mo ox mq mr ms oy mu mv mw oz my mz na pa nc nd ne go bj">Caching is disabled by default. It can be enabled by setting the database parameter <code class="cw pl pm pn po b"><a class="af nx" href="https://www.oracle.com/pls/topic/lookup?ctx=dblatest&amp;id=GUID-BC78F286-9D61-481F-8A37-2E4DC379E67C" rel="noopener ugc nofollow" target="_blank">CLIENT_RESULT_CACHE_SIZE</a></code> to 32K or greater, and optionally tuning the cache entry invalidation time parameter <code class="cw pl pm pn po b"><a class="af nx" href="https://www.oracle.com/pls/topic/lookup?ctx=dblatest&amp;id=GUID-78EDC1F7-8834-43FA-AC5A-98B1E1A3DC64" rel="noopener ugc nofollow" target="_blank">CLIENT_RESULT_CACHE_LAG</a></code>. The defaults for the parameters are 0 bytes and 3000 milliseconds, respectively.</p><p id="f94d" class="pw-post-body-paragraph mh mi gv mj b mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne go bj">If you are using pluggable databases the parameters can be set per-PDB.</p><p id="5a72" class="pw-post-body-paragraph mh mi gv mj b mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne go bj">If CRC is enabled (i.e <code class="cw pl pm pn po b"><a class="af nx" href="https://www.oracle.com/pls/topic/lookup?ctx=dblatest&amp;id=GUID-BC78F286-9D61-481F-8A37-2E4DC379E67C" rel="noopener ugc nofollow" target="_blank">CLIENT_RESULT_CACHE_SIZE</a></code> is 32K or more), then individual client applications can use different sizes by setting <code class="cw pl pm pn po b">sqlnet.ora</code> or <code class="cw pl pm pn po b">oraaccess.xml</code> parameters, see the <a class="af nx" href="https://www.oracle.com/pls/topic/lookup?ctx=dblatest&amp;id=GUID-4B68F0BB-16FA-40C6-BA13-CFD9A2B110A8" rel="noopener ugc nofollow" target="_blank">Oracle Call Interface documentation</a>.</p><p id="43b4" class="pw-post-body-paragraph mh mi gv mj b mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne go bj">Once CRC is enabled, caching of query result sets is then activated by one of:</p><ul class=""><li id="cb16" class="mh mi gv mj b mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne pb pc pd bj">Setting the table caching mode when creating a table: <code class="cw pl pm pn po b">CREATE TABLE mytable (...) RESULT_CACHE (MODE FORCE);</code></li><li id="8560" class="mh mi gv mj b mk pe mm mn mo pf mq mr ms pg mu mv mw ph my mz na pi nc nd ne pb pc pd bj">Modifying an existing table: <code class="cw pl pm pn po b">ALTER TABLE mytable RESULT_CACHE (MODE FORCE);</code></li><li id="08e5" class="mh mi gv mj b mk pe mm mn mo pf mq mr ms pg mu mv mw ph my mz na pi nc nd ne pb pc pd bj">Using an explicit query hint <code class="cw pl pm pn po b">SELECT /*+ RESULT_CACHE */ * FROM mytable;</code></li></ul><p id="c0ce" class="pw-post-body-paragraph mh mi gv mj b mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne go bj">The application must be using the separate, driver <a class="af nx" href="https://www.oracle.com/pls/topic/lookup?ctx=dblatest&amp;id=GUID-4947CAE8-1F00-4897-BB2B-7F921E495175" rel="noopener ugc nofollow" target="_blank">statement caching</a> feature. This is enabled by default for most drivers.</p><p id="3aca" class="pw-post-body-paragraph mh mi gv mj b mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne go bj">If CRC is activated at the table level, you can disable it for specific queries by using the hint <code class="cw pl pm pn po b">/*+ NO_RESULT_CACHE */</code></p><h1 id="8562" class="ny nz gv be oa ob oc od oe of og oh oi oj ok ol om on oo op oq or os ot ou ov bj">Python Example</h1><p id="8cc4" class="pw-post-body-paragraph mh mi gv mj b mk ow mm mn mo ox mq mr ms oy mu mv mw oz my mz na pa nc nd ne go bj">In my demo, I enabled caching by setting the database initialization parameters in my pluggable database:</p><pre class="ni nj nk nl nm pp po pq bo pr ba bj">$ sqlplus -l sys@localhost/orclcdb as sysdba<br />. . .SQL&gt; alter session set container=orclpdb1;Session altered.SQL&gt; alter system set client_result_cache_size=32K scope=spfile;System altered.SQL&gt; alter pluggable database orclpdb1 close;Pluggable database altered.SQL&gt; alter pluggable database orclpdb1 open;Pluggable database altered.SQL&gt; show parameter client_result_cacheNAME         TYPE  VALUE<br />------------------------------------ ----------- ------------------------------<br />client_result_cache_lag       big integer 3000<br />client_result_cache_size      big integer 32K</pre><p id="d986" class="pw-post-body-paragraph mh mi gv mj b mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne go bj">My demo app (code is <a class="af nx" href="https://gist.github.com/cjbj/c052a1645462351dcee68683077a3d0d" rel="noopener ugc nofollow" target="_blank">here</a>) is a Python Flask web app returning six records from a table <code class="cw pl pm pn po b">crcparts</code>:</p><pre class="ni nj nk nl nm pp po pq bo pr ba bj">create table crcparts<br />   (id        number primary key,<br />    category  varchar2(20),<br />    name      varchar2(20),<br />    price     number);</pre><p id="2ffe" class="pw-post-body-paragraph mh mi gv mj b mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne go bj">The app <a class="af nx" href="https://python-oracledb.readthedocs.io/en/latest/user_guide/initialization.html#enabling-python-oracledb-thick-mode" rel="noopener ugc nofollow" target="_blank">enables Thick mode</a>, which is currently a pre-requisite for using CRC in python-oracledb:</p><pre class="ni nj nk nl nm pp po pq bo pr ba bj">oracledb.init_oracle_client(lib_dir=ld)</pre><p id="1ada" class="pw-post-body-paragraph mh mi gv mj b mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne go bj">The app has two endpoint routes, <code class="cw pl pm pn po b">/usecrc</code> and <code class="cw pl pm pn po b">/nocrc</code> that respectively execute the SQL queries:</p><pre class="ni nj nk nl nm pp po pq bo pr ba bj">SELECT /*+ RESULT_CACHE */    * FROM CRCPARTSSELECT /*+ NO_RESULT_CACHE */ * FROM CRCPARTS</pre><p id="32f2" class="pw-post-body-paragraph mh mi gv mj b mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne go bj">The queries and application endpoints return the exact same results.</p><p id="7d7b" class="pw-post-body-paragraph mh mi gv mj b mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne go bj">The app also has an endpoint <code class="cw pl pm pn po b">/monitor</code> that queries <code class="cw pl pm pn po b">v$sqlarea</code> to show how many times the database executed the two SELECT statements:</p><pre class="ni nj nk nl nm pp po pq bo pr ba bj">cursor.execute(<br />    """select executions, sql_text<br />       from v$sqlarea<br />       where sql_text = :q1 or sql_text = :q2<br />       order by 2""",<br />    [QRY_CRC, QRY_NO_CRC])</pre><p id="5d94" class="pw-post-body-paragraph mh mi gv mj b mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne go bj">I started the application:</p><pre class="ni nj nk nl nm pp po pq bo pr ba bj">$ python3 app.py</pre><p id="ba39" class="pw-post-body-paragraph mh mi gv mj b mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne go bj">And initiated some load against both end points using the Apache benchmark utility. Representative samples are shown below.</p><p id="fb8b" class="pw-post-body-paragraph mh mi gv mj b mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne go bj"><strong class="mj gw">With CRC</strong></p><pre class="ni nj nk nl nm pp po pq bo pr ba bj">$ ab -n 1000 http://127.0.0.1:8080/usecrc<br />. . .<br />Time taken for tests:   13.457 seconds<br />Complete requests:      1000<br />. . .<br />Requests per second:    74.31 [#/sec] (mean)<br />Time per request:       13.457 [ms] (mean)<br />. . .</pre><p id="f51e" class="pw-post-body-paragraph mh mi gv mj b mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne go bj"><strong class="mj gw">Without CRC</strong></p><pre class="ni nj nk nl nm pp po pq bo pr ba bj">$ ab -n 1000 http://127.0.0.1:8080/nocrc<br />. . .<br />Time taken for tests:   22.359 seconds<br />Complete requests:      1000<br />. . .<br />Requests per second:    44.72 [#/sec] (mean)<br />Time per request:       22.359 [ms] (mean)<br />. . .</pre><p id="aa2f" class="pw-post-body-paragraph mh mi gv mj b mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne go bj"><strong class="mj gw">Results</strong></p><p id="221b" class="pw-post-body-paragraph mh mi gv mj b mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne go bj">You can see that the CRC-enabled endpoint was more efficient, serving the 1000 requests in almost half the time of the non-CRC endpoint. This also translates to reduced load on the database. This can be shown with the <code class="cw pl pm pn po b">/monitor</code> endpoint:</p><figure class="ni nj nk nl nm nn nf ng paragraph-image"><div class="nf ng px"><picture><source srcset="https://miro.medium.com/v2/resize:fit:640/format:webp/1*D_bkAVlCU4Pqe12X3y3oOw.png 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/1*D_bkAVlCU4Pqe12X3y3oOw.png 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/1*D_bkAVlCU4Pqe12X3y3oOw.png 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/1*D_bkAVlCU4Pqe12X3y3oOw.png 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/1*D_bkAVlCU4Pqe12X3y3oOw.png 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/1*D_bkAVlCU4Pqe12X3y3oOw.png 1100w, https://miro.medium.com/v2/resize:fit:1064/format:webp/1*D_bkAVlCU4Pqe12X3y3oOw.png 1064w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 532px" type="image/webp" /><source data-testid="og" srcset="https://miro.medium.com/v2/resize:fit:640/1*D_bkAVlCU4Pqe12X3y3oOw.png 640w, https://miro.medium.com/v2/resize:fit:720/1*D_bkAVlCU4Pqe12X3y3oOw.png 720w, https://miro.medium.com/v2/resize:fit:750/1*D_bkAVlCU4Pqe12X3y3oOw.png 750w, https://miro.medium.com/v2/resize:fit:786/1*D_bkAVlCU4Pqe12X3y3oOw.png 786w, https://miro.medium.com/v2/resize:fit:828/1*D_bkAVlCU4Pqe12X3y3oOw.png 828w, https://miro.medium.com/v2/resize:fit:1100/1*D_bkAVlCU4Pqe12X3y3oOw.png 1100w, https://miro.medium.com/v2/resize:fit:1064/1*D_bkAVlCU4Pqe12X3y3oOw.png 1064w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 532px" /></picture></div></figure><p id="a805" class="pw-post-body-paragraph mh mi gv mj b mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne go bj">Although we know the application executed 1000 queries in each case, the database never even saw 999 of the queries initiated by the <code class="cw pl pm pn po b">/usecrc</code> endpoint. Instead, the application got the results directly from the cache. This let the database handle other load, thus improving system scalability.</p><h1 id="0651" class="ny nz gv be oa ob oc od oe of og oh oi oj ok ol om on oo op oq or os ot ou ov bj">Conclusion</h1><p id="6284" class="pw-post-body-paragraph mh mi gv mj b mk ow mm mn mo ox mq mr ms oy mu mv mw oz my mz na pa nc nd ne go bj">Oracle Database’s Client Result Cache is a simple, efficient, integrated, managed cache that can dramatically improve application performance when querying lookup tables, and can significantly reduce database load. No application changes are needed. It is best for repeated queries against relatively small tables containing read-mostly or read-only data.</p><p id="6bc0" class="pw-post-body-paragraph mh mi gv mj b mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne go bj">CRC is a database feature available in all editions. It is a mature technology, having been released back in the 11g days. Enhancements continue to be made.</p><p id="42a1" class="pw-post-body-paragraph mh mi gv mj b mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne go bj">CRC is available to any “Thick” client that uses Oracle Client libraries, such as drivers for Python, Node.js, Go, PHP, Rust, and Oracle’s C API. It is also available in JDBC. It is currently not available in python-oracledb Thin mode or node-oracledb Thin mode, but support is on the roadmap.</p><h1 id="ba9f" class="ny nz gv be oa ob oc od oe of og oh oi oj ok ol om on oo op oq or os ot ou ov bj">Client Result Caching FAQ</h1><ol class=""><li id="b8d0" class="mh mi gv mj b mk ow mm mn mo ox mq mr ms oy mu mv mw oz my mz na pa nc nd ne py pc pd bj"><strong class="mj gw">What is Client Result Caching?</strong> CRC is an Oracle Database feature that stores results of queries (i.e. <code class="cw pl pm pn po b">SELECT</code> and <code class="cw pl pm pn po b">WITH</code> statements) in the client application so subsequent, identical queries don’t need to be sent to the database for processing.</li><li id="6f48" class="mh mi gv mj b mk pe mm mn mo pf mq mr ms pg mu mv mw ph my mz na pi nc nd ne py pc pd bj"><strong class="mj gw">How is Client Result Caching enabled?</strong> Set the database initialization parameter <code class="cw pl pm pn po b"><a class="af nx" href="https://www.oracle.com/pls/topic/lookup?ctx=dblatest&amp;id=GUID-BC78F286-9D61-481F-8A37-2E4DC379E67C" rel="noopener ugc nofollow" target="_blank">CLIENT_RESULT_CACHE_SIZE</a></code> to 32K or higher, and optionally tune <code class="cw pl pm pn po b"><a class="af nx" href="https://www.oracle.com/pls/topic/lookup?ctx=dblatest&amp;id=GUID-78EDC1F7-8834-43FA-AC5A-98B1E1A3DC64" rel="noopener ugc nofollow" target="_blank">CLIENT_RESULT_CACHE_LAG</a></code>. Use table annotations to mark tables as cacheable, or alternatively explicitly annotate queries on the client with the result cache hint <code class="cw pl pm pn po b">/*+ RESULT_CACHE */</code></li><li id="9de6" class="mh mi gv mj b mk pe mm mn mo pf mq mr ms pg mu mv mw ph my mz na pi nc nd ne py pc pd bj"><strong class="mj gw">Which Oracle Database APIs support CRC?</strong> Any “Thick” client that uses Oracle Client libraries, such as drivers for Python, Node.js, Go, PHP, Rust, Ruby, and Oracle’s C API. It is also available in JDBC.</li><li id="64a1" class="mh mi gv mj b mk pe mm mn mo pf mq mr ms pg mu mv mw ph my mz na pi nc nd ne py pc pd bj"><strong class="mj gw">How many caches are there?</strong> There is one cache per client process. It is shared by all sessions in each process.</li><li id="d6e4" class="mh mi gv mj b mk pe mm mn mo pf mq mr ms pg mu mv mw ph my mz na pi nc nd ne py pc pd bj"><strong class="mj gw">Can one session see results of other sessions?</strong> Sessions logged in as User-A cannot see the results cached by sessions logged in as User-B.</li><li id="962c" class="mh mi gv mj b mk pe mm mn mo pf mq mr ms pg mu mv mw ph my mz na pi nc nd ne py pc pd bj"><strong class="mj gw">What are table annotations?</strong> The table annotation <code class="cw pl pm pn po b">RESULT_CACHE (MODE FORCE)</code>with<code class="cw pl pm pn po b">ALTER TABLE</code> and <code class="cw pl pm pn po b">CREATE TABLE</code> can enable caching on a table without needing any application changes. All tables used in the query need to have <code class="cw pl pm pn po b">FORCE</code> mode otherwise a query hint is needed for caching. To check, do: <code class="cw pl pm pn po b">select substr(table_name,1,25), result_cache from user_tables</code></li><li id="0aaf" class="mh mi gv mj b mk pe mm mn mo pf mq mr ms pg mu mv mw ph my mz na pi nc nd ne py pc pd bj"><strong class="mj gw">Does client result caching need the tables to be read only?</strong> No. The cache is sensitive to database and session level changes that can affect the result set. However it is most efficient for mostly static tables.</li><li id="2a59" class="mh mi gv mj b mk pe mm mn mo pf mq mr ms pg mu mv mw ph my mz na pi nc nd ne py pc pd bj"><strong class="mj gw">What datatypes are supported? </strong>Queries involving basic datatypes from user-owned tables are supported. Queries involving LOBs, LONGs, cursors, database links, complex types, or PL/SQL functions in the SELECT list will not have results cached.</li><li id="3d22" class="mh mi gv mj b mk pe mm mn mo pf mq mr ms pg mu mv mw ph my mz na pi nc nd ne py pc pd bj"><strong class="mj gw">How does Oracle Client keep results consistent?</strong> Every round-trip from the application to the database comes back with any invalidations for the client cache entries. These changes invalidate the relevant cache results (not the whole cache). The next application query execution will be sent to the database and the new results will be loaded into the client cache. If the application is not making any round-trips then, after a configurable time interval, the client library will always send the next query execution to the database. Hence unnecessary round-trips, e.g. polling to server, is not required to check for updates. The cache is also sensitive to session level changes like NLS settings, roles, etc. that may affect the result set. So the caching and consistency with respect to database and session changes are transparent to the application.</li><li id="a79f" class="mh mi gv mj b mk pe mm mn mo pf mq mr ms pg mu mv mw ph my mz na pi nc nd ne py pc pd bj"><strong class="mj gw">How is CRC related to the server result cache?</strong> The server result cache caches top-level queries and sub-queries in the SGA on the server. It uses the same SQL statement result cache hints but is a different feature from the Client Result Cache. The CRC is for top-level queries executed from applications. Both these two result cache features can be enabled or disabled independently. Note the server cache will optimize “execute” and “fetch” round-trips when they reach the server. The client result cache will prevent “execute” and “fetch” round-trips from reaching the server by making the query execution local to the application</li><li id="72fe" class="mh mi gv mj b mk pe mm mn mo pf mq mr ms pg mu mv mw ph my mz na pi nc nd ne py pc pd bj"><strong class="mj gw">How is CRC related to statement caching?</strong> Statement caching is a separate client cache that stores the text of SQL statements and is used to reduce the cost of statement parsing and of metadata transfers from the database. The only relationship is that CRC requires statement caching to be enabled.</li></ol><h1 id="f39a" class="ny nz gv be oa ob oc od oe of og oh oi oj ok ol om on oo op oq or os ot ou ov bj">References</h1><ul class=""><li id="1300" class="mh mi gv mj b mk ow mm mn mo ox mq mr ms oy mu mv mw oz my mz na pa nc nd ne pb pc pd bj">Oracle Database Performance Tuning Guide <a class="af nx" href="https://www.oracle.com/pls/topic/lookup?ctx=dblatest&amp;id=GUID-39C521D4-5C6E-44B1-B7C7-DEADD7D9CAF0" rel="noopener ugc nofollow" target="_blank">Client Result Cache Concepts</a></li><li id="4922" class="mh mi gv mj b mk pe mm mn mo pf mq mr ms pg mu mv mw ph my mz na pi nc nd ne pb pc pd bj">Database Development Guide <a class="af nx" href="https://www.oracle.com/pls/topic/lookup?ctx=dblatest&amp;id=GUID-35CB2592-7588-4C2D-9075-6F639F25425E" rel="noopener ugc nofollow" target="_blank">Using Client Result Cache</a></li><li id="8abf" class="mh mi gv mj b mk pe mm mn mo pf mq mr ms pg mu mv mw ph my mz na pi nc nd ne pb pc pd bj">Database initialization parameter <code class="cw pl pm pn po b"><a class="af nx" href="https://www.oracle.com/pls/topic/lookup?ctx=dblatest&amp;id=GUID-BC78F286-9D61-481F-8A37-2E4DC379E67C" rel="noopener ugc nofollow" target="_blank">CLIENT_RESULT_CACHE_SIZE</a></code></li><li id="af50" class="mh mi gv mj b mk pe mm mn mo pf mq mr ms pg mu mv mw ph my mz na pi nc nd ne pb pc pd bj">Database initialization parameter <code class="cw pl pm pn po b"><a class="af nx" href="https://www.oracle.com/pls/topic/lookup?ctx=dblatest&amp;id=GUID-78EDC1F7-8834-43FA-AC5A-98B1E1A3DC64" rel="noopener ugc nofollow" target="_blank">CLIENT_RESULT_CACHE_LAG</a></code></li><li id="dadc" class="mh mi gv mj b mk pe mm mn mo pf mq mr ms pg mu mv mw ph my mz na pi nc nd ne pb pc pd bj"><code class="cw pl pm pn po b">sqlnet.ora</code> and <code class="cw pl pm pn po b">oraaccess.xml</code> parameters <a class="af nx" href="https://www.oracle.com/pls/topic/lookup?ctx=dblatest&amp;id=GUID-4B68F0BB-16FA-40C6-BA13-CFD9A2B110A8" rel="noopener ugc nofollow" target="_blank">Oracle Call Interface<br />documentation</a></li><li id="52b0" class="mh mi gv mj b mk pe mm mn mo pf mq mr ms pg mu mv mw ph my mz na pi nc nd ne pb pc pd bj">Python-oracledb driver <a class="af nx" href="https://pypi.org/project/oracledb/" rel="noopener ugc nofollow" target="_blank">https://pypi.org/project/oracledb/</a></li></ul></div>]]></description>
      <link>https://medium.com/oracledevs/query-result-caching-for-fast-database-applications-469d689c9dab?source=rss-adc937c3a9d------2</link>
      <guid>https://medium.com/oracledevs/query-result-caching-for-fast-database-applications-469d689c9dab?source=rss-adc937c3a9d------2</guid>
      <pubDate>Thu, 15 Aug 2024 09:39:00 +0200</pubDate>
    </item>
    <item>
      <title><![CDATA[PHP 8.4.0 Beta 3 now available for testing - PHP: Hypertext Preprocessor]]></title>
      <description><![CDATA[<div><header class="title"><time datetime="2024-08-15T13:45:25+00:00">15 Aug 2024</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the release of PHP 8.4.0, Beta 3. This is the first beta release, continuing the PHP 8.4 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php84">PHP Wiki</a>.</p><p>For source downloads of PHP 8.4.0, Beta 3 please visit the <a href="https://downloads.php.net/~calvinb">download page</a>.</p><p>Please carefully test this version and report any issues found in the <a href="https://github.com/php/php-src/issues">bug reporting system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.4.0beta3/NEWS">NEWS</a> file or the <a href="https://github.com/php/php-src/blob/php-8.4.0beta3/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be Beta 4, planned for 29 August 2024.</p><p>The signatures for the release can be found in <a href="https://gist.github.com/NattyNarwhal/fdd2de9d3b165143d376679258811c15">the manifest</a> or on <a href="https://qa.php.net/">the QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></div><div><header class="title"><time datetime="2024-08-01T23:21:43+00:00">01 Aug 2024</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the second testing release of PHP 8.4.0, Alpha 4. This continues the PHP 8.4 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php84">PHP Wiki</a>.</p><p>For source downloads of PHP 8.4.0 Alpha 4 please visit the <a href="https://downloads.php.net/~saki/">download page</a>.</p><p>Please carefully test this version and report any issues found in the <a href="https://github.com/php/php-src/issues">bug reporting system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.4.0alpha4/NEWS">NEWS</a> file, or the <a href="https://github.com/php/php-src/blob/php-8.4.0alpha4/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be Beta 1, planned for 15 Aug 2024.</p><p>The signatures for the release can be found in <a href="https://gist.github.com/SakiTakamachi/6ef16057e96947aa030408db244718a7">the manifest</a> or on <a href="https://qa.php.net/">the QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></div><div><header class="title"><time datetime="2024-08-01T16:12:06+00:00">01 Aug 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.22. This is a bug fix release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.22 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.22">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-08-01T13:28:53+00:00">01 Aug 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.3.10. This is a bug fix release.</p><p>All PHP 8.3 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.3.10 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.3.10">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-07-18T13:30:46+00:00">18 Jul 2024</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the second testing release of PHP 8.4.0, Alpha 2. This continues the PHP 8.4 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php84">PHP Wiki</a>.</p><p>For source downloads of PHP 8.4.0 Alpha 2 please visit the <a href="https://downloads.php.net/~calvinb/">download page</a>.</p><p>Please carefully test this version and report any issues found in the <a href="https://github.com/php/php-src/issues">bug reporting system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.4.0alpha2/NEWS">NEWS</a> file, or the <a href="https://github.com/php/php-src/blob/php-8.4.0alpha2/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be Alpha 3, planned for 1 Aug 2024.</p><p>The signatures for the release can be found in <a href="https://gist.github.com/NattyNarwhal/74b55b8fcc6411ff8db05f87a6f41864">the manifest</a> or on <a href="https://qa.php.net/">the QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></div><div><header class="title"><time datetime="2024-07-05T13:22:12+00:00">05 Jul 2024</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the first testing release of PHP 8.4.0, Alpha 1. This starts the PHP 8.4 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php84">PHP Wiki</a>.</p><p>For source downloads of PHP 8.4.0 Alpha 1 please visit the <a href="https://downloads.php.net/~saki/">download page</a>.</p><p>Please carefully test this version and report any issues found using <a href="https://github.com/php/php-src/issues">the bug tracking system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.4.0alpha1/NEWS">NEWS</a> file, or the <a href="https://github.com/php/php-src/blob/php-8.4.0alpha1/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be Alpha 2, planned for 18 Jul 2024.</p><p>The signatures for the release can be found in the <a href="https://gist.github.com/SakiTakamachi/d3e32b780590319bee72d8402593a3ca">manifest</a> or on the <a href="https://qa.php.net/">QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></div><div><header class="title"><time datetime="2024-07-04T22:59:58+00:00">04 Jul 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.3.9. This is a bug fix release.</p><p>All PHP 8.3 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.3.9 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.3.9">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-07-04T14:43:24+00:00">04 Jul 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.21. This is a bug fix release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.21 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.21">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-06-06T14:56:47+00:00">06 Jun 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.20. This is a security release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.20 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.20">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-06-06T14:42:14+00:00">06 Jun 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.3.8. This is a security release.</p><p>All PHP 8.3 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.3.8 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.3.8">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-06-06T14:12:51+00:00">06 Jun 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.1.29. This is a security release.</p><p>All PHP 8.1 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.1.29 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.1.29">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-05-09T14:40:06+00:00">09 May 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.3.7. This is a bug fix release.</p><p>All PHP 8.3 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.3.7 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.3.7">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-05-09T13:48:33+00:00">09 May 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.19. This is a bug fix release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.19 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.19">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-04-24T18:40:29+00:00">24 Apr 2024</time>
</header><div class="newscontent"><p>EDIT 2024-04-25: Clarified when a PHP application is vulnerable to this bug.</p><p>Recently, a bug in <strong>glibc</strong> version 2.39 and older (<a href="https://nvd.nist.gov/vuln/detail/CVE-2024-2961">CVE-2024-2961</a>) was uncovered where a buffer overflow in character set conversions <strong>to</strong> the ISO-2022-CN-EXT character set can result in remote code execution.</p><p>This specific buffer overflow in glibc is exploitable through PHP, which exposes the iconv functionality of glibc to do character set conversions via the <a href="https://www.php.net/manual/en/function.iconv.php">iconv extension</a>. Although the bug is exploitable in the context of the PHP Engine, the bug is not in PHP. It is also not directly exploitable remotely.</p><p>The bug is exploitable, <strong>if and only if</strong>, the PHP application calls iconv <a href="https://www.php.net/manual/en/ref.iconv.php">functions</a> or <a href="https://www.php.net/manual/en/filters.convert.php#filters.convert.iconv">filters</a> with user-supplied character sets.</p><p>Applications are <strong>not</strong> vulnerable if:</p><ul><li>Glibc security updates from the distribution have been installed.</li>
<li>Or the iconv extension is not loaded.</li>
<li>Or the vulnerable character set has been removed from gconv-modules-extra.conf.</li>
<li>Or the application passes only specifically allowed character sets to iconv.</li>
</ul><p>Moreover, when using a user-supplied character set, it is good practice for applications to accept only specific charsets that have been explicitly allowed by the application. One example of how this can be done is by using an allow-list and the <a href="https://www.php.net/manual/en/function.array-search"><code>array_search()</code></a> function to check the encoding before passing it to iconv. For example: <code>array_search($charset, $allowed_list, true)</code></p><p>There are numerous reports online with titles like "Mitigating the iconv Vulnerability for PHP (CVE-2024-2961)" or "PHP Under Attack". These titles are misleading as this is <strong>not</strong> a bug in PHP itself.</p><p>If your PHP application is vulnerable, we first recommend to check if your Linux distribution has already published patched variants of glibc. <a href="https://security-tracker.debian.org/tracker/CVE-2024-2961">Debian</a>, CentOS, and others, have already done so, and please upgrade as soon as possible.</p><p>Once an update is available in glibc, updating that package on your Linux machine will be enough to alleviate the issue. You do not need to update PHP, as glibc is a dynamically linked library.</p><p>If your Linux distribution has not published a patched version of glibc, there is no fix for this issue. However, there exists a workaround described in <a href="https://rockylinux.org/news/glibc-vulnerability-april-2024/">GLIBC Vulnerability on Servers Serving PHP</a> which explains a way on how to remove the problematic character set from glibc. Perform this procedure for every gconv-modules-extra.conf file that is available on your system.</p><p>PHP users on Windows are not affected.</p><p>Therefore, a new version of PHP will not be released for this vulnerability.</p></div></div><div><header class="title"><time datetime="2024-04-12T15:42:40+00:00">12 Apr 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.1.28. This is a security release.</p><p>All PHP 8.1 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.1.28 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.1.28">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-04-11T14:34:04+00:00">11 Apr 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.3.6. This is a security release.</p><p>All PHP 8.3 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.3.6 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.3.6">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-04-11T13:37:51+00:00">11 Apr 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.18. This is a security release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.18 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.18">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-03-14T21:02:45+00:00">14 Mar 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.3.4. This is a bug fix release.</p><p>All PHP 8.3 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.3.4 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.3.4">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-03-14T15:21:29+00:00">14 Mar 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.17. This is a bug fix release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.17 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.17">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-02-15T13:36:20-05:00">15 Feb 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.16. This is a bug fix release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.16 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.16">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-02-15T15:48:46+00:00">15 Feb 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.3.3. This is a bug fix release.</p><p>All PHP 8.3 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.3.3 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.3.3">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-01-18T15:35:45+00:00">18 Jan 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.15. This is a bug fix release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.15 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.15">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-01-18T14:47:41+00:00">18 Jan 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.3.2. This is a bug fix release.</p><p>All PHP 8.3 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.3.2 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.3.2">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2023-12-21T14:28:29-05:00">21 Dec 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.14. This is a bug fix release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.14 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.14">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2023-12-21T16:12:41+00:00">21 Dec 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.1.27. This is a bug fix release.</p><p>All PHP 8.1 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.1.27 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.1.27">ChangeLog</a>.</p></div></div>]]></description>
      <link>https://www.php.net/index.php#2024-08-15-1</link>
      <guid>https://www.php.net/index.php#2024-08-15-1</guid>
      <pubDate>Thu, 15 Aug 2024 02:00:00 +0200</pubDate>
    </item>
    <item>
      <title><![CDATA[PHP Internals News: Episode 93: Never For Parameter Types - Derick Rethans]]></title>
      <description><![CDATA[]]></description>
      <link>https://deri/</link>
      <guid>https://deri/</guid>
      <pubDate>Thu, 08 Aug 2024 20:01:00 +0200</pubDate>
    </item>
    <item>
      <title><![CDATA[PHP Internals News: Episode 93: Never For Parameter Types - Derick Rethans]]></title>
      <description><![CDATA[<div class="c30"><p>00000000000 4000000004 00000000004</p><p>000000000004 400000000000000 00000000000</p><p>000000000000 4000000000000000000 000000000000</p><p>0000000000000 000000000000000000000 0000000000000</p><p>00000000000000 00000000000000000000004 00000000000004</p><p>000000000000004 0000000000 000000000 00000000000000</p><p>000000000000000 000000000 000000004 000000000000000</p><p>0000000400000000 400000000 000000000 0000004000000000</p><p>0000000 000000000 000000000 000000000 40000004 000000004</p><p>0000000 000000004 000000000 000000000 4000000 00000000</p><p>0000004 00000000 000000000 000000000 0000000 400000000</p><p>40000004 400000000 0000000004 000000000 0000000 000000000</p><p>4000000 000000000 000000000 000000000 0000000 000000000</p><p>0000000 000000000 000000000 000000000 0000000 00000000</p><p>0000000 00000000 000000000 0000000004 0000000 400000000</p><p>0000000 00000000 000000000 000000000 0000000 000000000</p><p>0000000 000000000 000000000 000000000 0000000 000000000</p><p>0000000 000000000 000000000 000000000 0000000 00000000</p><p>00000000000000000000000000000 000000000 000000000 00000000000000000000000000000</p><p>00000000000000000000000000000 000000000 000000000 00000000000000000000000000000</p><p>00000000000000000000000000000 000000000 000000000 000000000000000000000000000000</p><p>000000000000000000000000000000 000000000 000000000 00000000000000000000000000000</p><p>00000000000000000000000000000 400000000 000000000 00000000000000000000000000000</p><p>44444444444444440000000044444 000000000 000000000 44444444444444400000000044444</p><p>000000000 00000000000000000000000 000000000</p><p>000000000 000000000000000000000 000000004</p><p>00000000 0000000000000000000 00000000</p><p>00000000 4000000000000000 000000000</p><p>000000000 0000000000 000000000</p></div>
<div class="c31">Sorry, but the page you are requesting is not here. Please leave a message after the beep.<p>BEEP!</p></div>]]></description>
      <link>https://derickrethans.nl/phpinternalsn</link>
      <guid>https://derickrethans.nl/phpinternalsn</guid>
      <pubDate>Wed, 07 Aug 2024 22:02:00 +0200</pubDate>
    </item>
    <item>
      <title><![CDATA[Xdebug Update: July 2024 - Derick Rethans]]></title>
      <description><![CDATA[<p>In this monthly update I explain what happened with Xdebug development in the past month. These are normally published on the first Tuesday on or after the 5th of each month.</p><p><a href="https://github.com/sponsors/derickr/">GitHub</a> and <a href="https://xdebug.org/support">Pro/Business supporters</a> will get it earlier, around the first of each month.</p><p>On GitHub sponsors, I am currently 42% towards my $2,500 per month goal, which is set to allow continued <strong>maintenance</strong> of Xdebug. This is less than last month.</p><p>If you are leading a team or company, then it is also possible to support Xdebug through <a href="https://xdebug.org/support">a subscription</a>.</p><p>In the last month, I spend around 15 hours on Xdebug, with 21 hours funded. I also spent 6 hours on the Native Path Mapping project.</p><div class="articleSubSection"><h2>PHP 8.4</h2><p>I spent some time making sure that Xdebug will be ready for PHP 8.4, once that comes out later in the year. There are always some incompatibilities, such as the new <a href="https://github.com/php/php-src/pull/12461">frameless calls</a> and some deprecations.</p><p>I also did a deep dive into supporting a potential large change into the way PHP handles the <code>exit</code> keyword. There is a <a href="https://wiki.php.net/rfc/exit-as-function">proposal</a> to change that from a language instruction to an actual function, but this impacts Xdebug fairly significantly — it uses the instruction for path and branch analysis, and to make sure profiling files get stored on disk in full. At the moment, it is unsure whether this change will be adopted.</p><p>Beyond preparatory work for PHP 8.4, I also spend some time on improving the out-of-band socket communication support to make it easier for IDEs to use. This work will continue to be ongoing for a while.</p></div><div class="articleSubSection"><h2>Native Xdebug Path Mapping</h2><p>I have started on the <a href="https://xdebug.org/funding/001-native-path-mapping">Native Xdebug Path Mapping</a> project.</p><p>As this is a separately funded project, I don't classify the hours that I worked on this in "Xdebug Hours". I also publish a separate report on the <a href="https://xdebug.org/funding/001-native-path-mapping">project page</a>.</p><p>As an exception, I am including it here:</p><p>In this first month, or rather, the last week of July, I have been working on setting up a testing framework for the parser. Previously Xdebug only had tests in <a href="https://qa.php.net/write-test.php">PHPT</a> form, PHP's standard for testing syntax and functions. However, this is rather more an integration test framework, as it compares the output of a script with an expected output.</p><p>For low-level features, such as testing the implementation of the parser that parses the path mapping files, PHPT tests are not suitable. Instead, the testing framework tests the return values and generated structures directly, without PHP having to be involved. The <a href="https://cpputest.github.io/manual.html">CppUTest</a> framework that I use for this, is much more similar to PHPUnit. It is also a framework that I have used for testing <a href="https://github.com/derickr/timelib">timelib</a>, the library that powers PHP and MongoDB's date/time functionality.</p><p>Beyond the testing framework, I have also made a start on the parser itself. It can currently parse the remote_prefix and local_prefix stanzas, as well as mapping lines, although it does not distinguish between directory maps, file maps, or line maps yet, nor does it apply the prefix stanzas yet.</p></div><div class="articleSubSection"><h2>Xdebug Videos</h2><p>I have created no new videos since last month, but you can see all the previous ones on my <a href="https://www.youtube.com/playlist?list=PLg9Kjjye-m1g_eXpdaifUqLqALLqZqKd4">channel</a>.</p><p>If you have any suggestions, feel free to reach out to <a href="https://phpc.social/@derickr">me on Mastodon</a> or via <a href="http://derickrethans/who.html">email</a>.</p></div><div class="articleSubSection"><h2>Business Supporter Scheme and Funding</h2><p>In the last month, one new business supporter signed up:</p><ul><li>
<p><a href="https://www.clever-age.com/">Clever Age</a>.</p>
</li>
</ul><p>Besides business support, I also maintain a <a href="https://www.patreon.com/derickr">Patreon</a> page, a profile on <a href="https://github.com/sponsors/derickr">GitHub sponsors</a>, as well as an <a href="https://opencollective.com/xdebug">OpenCollective</a> organisation.</p><p>If you want to contribute to specific projects, you can find those on the <a href="https://xdebug.org/funding">Projects</a> page.</p></div><div class="articleSubSection"><h2>Xdebug Cloud</h2><p>Xdebug Cloud is the <em>Proxy As A Service</em> platform to allow for debugging in more scenarios, where it is hard, or impossible, to have Xdebug make a connection to the IDE. It is continuing to operate as Beta release.</p><p>Packages start at £49/month, and I have recently introduced a package for larger companies. This has a larger initial set of tokens, and discounted extra tokens.</p><p>If you want to be kept up to date with Xdebug Cloud, please sign up to the <a href="https://xdebug.cloud/newsletter">mailinglist</a>, which I will use to send out an update not more than once a month.</p></div>]]></description>
      <link>https://derickrethans.nl/xdebug-update-july-2024.html</link>
      <guid>https://derickrethans.nl/xdebug-update-july-2024.html</guid>
      <pubDate>Wed, 07 Aug 2024 19:10:00 +0200</pubDate>
    </item>
    <item>
      <title><![CDATA[Installing Oracle Instant Client for Apple macOS ARM64 (M1/M2/M3) - Christopher Jones]]></title>
      <description><![CDATA[<div><div></div><p id="1958" class="pw-post-body-paragraph mx my gv mz b na nb nc nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns nt nu go bj">In case you missed it, Oracle Instant Client is available for macOS ARM64. See the <a class="af nv" rel="noopener" href="https://medium.com/@sharad-chandran/oracle-instant-client-macos-arm64-for-apple-m1-m2-m3-platforms-is-now-available-950f1bc041f9">release announcement</a> post by my colleague <a class="nw iu fd" href="https://medium.com/u/12606d16645a" rel="noopener" target="_blank">Sharad Chandran</a>.</p><figure class="oa ob oc od oe of nx ny paragraph-image"><div role="button" tabindex="0" class="og oh fk oi bg oj"><div class="nx ny nz"><picture><source srcset="https://miro.medium.com/v2/resize:fit:640/format:webp/0*IQo0a57imCaoP0vC 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/0*IQo0a57imCaoP0vC 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/0*IQo0a57imCaoP0vC 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/0*IQo0a57imCaoP0vC 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/0*IQo0a57imCaoP0vC 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/0*IQo0a57imCaoP0vC 1100w, https://miro.medium.com/v2/resize:fit:1400/format:webp/0*IQo0a57imCaoP0vC 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" type="image/webp" /><source data-testid="og" srcset="https://miro.medium.com/v2/resize:fit:640/0*IQo0a57imCaoP0vC 640w, https://miro.medium.com/v2/resize:fit:720/0*IQo0a57imCaoP0vC 720w, https://miro.medium.com/v2/resize:fit:750/0*IQo0a57imCaoP0vC 750w, https://miro.medium.com/v2/resize:fit:786/0*IQo0a57imCaoP0vC 786w, https://miro.medium.com/v2/resize:fit:828/0*IQo0a57imCaoP0vC 828w, https://miro.medium.com/v2/resize:fit:1100/0*IQo0a57imCaoP0vC 1100w, https://miro.medium.com/v2/resize:fit:1400/0*IQo0a57imCaoP0vC 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" /></picture></div></div><figcaption class="ol fe om nx ny on oo be b bf z dt">Photo by <a class="af nv" href="https://unsplash.com/@nate_dumlao?utm_source=medium&amp;utm_medium=referral" rel="noopener ugc nofollow" target="_blank">Nathan Dumlao</a> on <a class="af nv" href="https://unsplash.com/?utm_source=medium&amp;utm_medium=referral" rel="noopener ugc nofollow" target="_blank">Unsplash</a></figcaption></figure><p id="4774" class="pw-post-body-paragraph mx my gv mz b na nb nc nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns nt nu go bj">I commonly install the ‘Basic’ package to give me the Oracle Client libraries needed for runtime by tools &amp; Thick drivers, the ‘SQL*Plus’ package to give me a command line SQL query tool, and the ‘SDK’ package to give me header files (because I still build OCI-based programs like the PHP OCI8 driver):</p><pre class="oa ob oc od oe op oq or bo os ba bj">curl -O https://download.oracle.com/otn_software/mac/instantclient/instantclient-basic-macos-arm64.dmg<br />curl -O https://download.oracle.com/otn_software/mac/instantclient/instantclient-sqlplus-macos-arm64.dmg<br />curl -O https://download.oracle.com/otn_software/mac/instantclient/instantclient-sdk-macos-arm64.dmghdiutil mount instantclient-basic-macos-arm64.dmg<br />hdiutil mount instantclient-sqlplus-macos-arm64.dmg<br />hdiutil mount instantclient-sdk-macos-arm64.dmg/Volumes/instantclient-basic-macos*/install_ic.shhdiutil unmount /Volumes/instantclient-basic-*/<br />hdiutil unmount /Volumes/instantclient-sqlplus-*/<br />hdiutil unmount /Volumes/instantclient-sdk-*/</pre><p id="9dbe" class="pw-post-body-paragraph mx my gv mz b na nb nc nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns nt nu go bj">Check the <a class="af nv" href="https://www.oracle.com/database/technologies/instant-client/macos-arm64-downloads.html" rel="noopener ugc nofollow" target="_blank">download page</a> for the latest links and other packages.</p></div>]]></description>
      <link>https://medium.com/oracledevs/installing-oracle-instant-client-for-apple-macos-arm64-m1-m2-m3-2c81f246feb9?source=rss-adc937c3a9d------2</link>
      <guid>https://medium.com/oracledevs/installing-oracle-instant-client-for-apple-macos-arm64-m1-m2-m3-2c81f246feb9?source=rss-adc937c3a9d------2</guid>
      <pubDate>Fri, 02 Aug 2024 00:26:00 +0200</pubDate>
    </item>
    <item>
      <title><![CDATA[PHP 8.4.0 Alpha 4 available for testing - PHP: Hypertext Preprocessor]]></title>
      <description><![CDATA[<div><header class="title"><time datetime="2024-08-01T23:21:43+00:00">01 Aug 2024</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the second testing release of PHP 8.4.0, Alpha 4. This continues the PHP 8.4 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php84">PHP Wiki</a>.</p><p>For source downloads of PHP 8.4.0 Alpha 4 please visit the <a href="https://downloads.php.net/~saki/">download page</a>.</p><p>Please carefully test this version and report any issues found in the <a href="https://github.com/php/php-src/issues">bug reporting system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.4.0alpha4/NEWS">NEWS</a> file, or the <a href="https://github.com/php/php-src/blob/php-8.4.0alpha4/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be Beta 1, planned for 15 Aug 2024.</p><p>The signatures for the release can be found in <a href="https://gist.github.com/SakiTakamachi/6ef16057e96947aa030408db244718a7">the manifest</a> or on <a href="https://qa.php.net/">the QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></div><div><header class="title"><time datetime="2024-08-01T16:12:06+00:00">01 Aug 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.22. This is a bug fix release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.22 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.22">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-08-01T13:28:53+00:00">01 Aug 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.3.10. This is a bug fix release.</p><p>All PHP 8.3 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.3.10 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.3.10">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-07-18T13:30:46+00:00">18 Jul 2024</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the second testing release of PHP 8.4.0, Alpha 2. This continues the PHP 8.4 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php84">PHP Wiki</a>.</p><p>For source downloads of PHP 8.4.0 Alpha 2 please visit the <a href="https://downloads.php.net/~calvinb/">download page</a>.</p><p>Please carefully test this version and report any issues found in the <a href="https://github.com/php/php-src/issues">bug reporting system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.4.0alpha2/NEWS">NEWS</a> file, or the <a href="https://github.com/php/php-src/blob/php-8.4.0alpha2/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be Alpha 3, planned for 1 Aug 2024.</p><p>The signatures for the release can be found in <a href="https://gist.github.com/NattyNarwhal/74b55b8fcc6411ff8db05f87a6f41864">the manifest</a> or on <a href="https://qa.php.net/">the QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></div><div><header class="title"><time datetime="2024-07-05T13:22:12+00:00">05 Jul 2024</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the first testing release of PHP 8.4.0, Alpha 1. This starts the PHP 8.4 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php84">PHP Wiki</a>.</p><p>For source downloads of PHP 8.4.0 Alpha 1 please visit the <a href="https://downloads.php.net/~saki/">download page</a>.</p><p>Please carefully test this version and report any issues found using <a href="https://github.com/php/php-src/issues">the bug tracking system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.4.0alpha1/NEWS">NEWS</a> file, or the <a href="https://github.com/php/php-src/blob/php-8.4.0alpha1/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be Alpha 2, planned for 18 Jul 2024.</p><p>The signatures for the release can be found in the <a href="https://gist.github.com/SakiTakamachi/d3e32b780590319bee72d8402593a3ca">manifest</a> or on the <a href="https://qa.php.net/">QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></div><div><header class="title"><time datetime="2024-07-04T22:59:58+00:00">04 Jul 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.3.9. This is a bug fix release.</p><p>All PHP 8.3 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.3.9 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.3.9">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-07-04T14:43:24+00:00">04 Jul 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.21. This is a bug fix release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.21 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.21">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-06-06T14:56:47+00:00">06 Jun 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.20. This is a security release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.20 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.20">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-06-06T14:42:14+00:00">06 Jun 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.3.8. This is a security release.</p><p>All PHP 8.3 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.3.8 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.3.8">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-06-06T14:12:51+00:00">06 Jun 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.1.29. This is a security release.</p><p>All PHP 8.1 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.1.29 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.1.29">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-05-09T14:40:06+00:00">09 May 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.3.7. This is a bug fix release.</p><p>All PHP 8.3 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.3.7 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.3.7">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-05-09T13:48:33+00:00">09 May 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.19. This is a bug fix release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.19 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.19">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-04-24T18:40:29+00:00">24 Apr 2024</time>
</header><div class="newscontent"><p>EDIT 2024-04-25: Clarified when a PHP application is vulnerable to this bug.</p><p>Recently, a bug in <strong>glibc</strong> version 2.39 and older (<a href="https://nvd.nist.gov/vuln/detail/CVE-2024-2961">CVE-2024-2961</a>) was uncovered where a buffer overflow in character set conversions <strong>to</strong> the ISO-2022-CN-EXT character set can result in remote code execution.</p><p>This specific buffer overflow in glibc is exploitable through PHP, which exposes the iconv functionality of glibc to do character set conversions via the <a href="https://www.php.net/manual/en/function.iconv.php">iconv extension</a>. Although the bug is exploitable in the context of the PHP Engine, the bug is not in PHP. It is also not directly exploitable remotely.</p><p>The bug is exploitable, <strong>if and only if</strong>, the PHP application calls iconv <a href="https://www.php.net/manual/en/ref.iconv.php">functions</a> or <a href="https://www.php.net/manual/en/filters.convert.php#filters.convert.iconv">filters</a> with user-supplied character sets.</p><p>Applications are <strong>not</strong> vulnerable if:</p><ul><li>Glibc security updates from the distribution have been installed.</li>
<li>Or the iconv extension is not loaded.</li>
<li>Or the vulnerable character set has been removed from gconv-modules-extra.conf.</li>
<li>Or the application passes only specifically allowed character sets to iconv.</li>
</ul><p>Moreover, when using a user-supplied character set, it is good practice for applications to accept only specific charsets that have been explicitly allowed by the application. One example of how this can be done is by using an allow-list and the <a href="https://www.php.net/manual/en/function.array-search"><code>array_search()</code></a> function to check the encoding before passing it to iconv. For example: <code>array_search($charset, $allowed_list, true)</code></p><p>There are numerous reports online with titles like "Mitigating the iconv Vulnerability for PHP (CVE-2024-2961)" or "PHP Under Attack". These titles are misleading as this is <strong>not</strong> a bug in PHP itself.</p><p>If your PHP application is vulnerable, we first recommend to check if your Linux distribution has already published patched variants of glibc. <a href="https://security-tracker.debian.org/tracker/CVE-2024-2961">Debian</a>, CentOS, and others, have already done so, and please upgrade as soon as possible.</p><p>Once an update is available in glibc, updating that package on your Linux machine will be enough to alleviate the issue. You do not need to update PHP, as glibc is a dynamically linked library.</p><p>If your Linux distribution has not published a patched version of glibc, there is no fix for this issue. However, there exists a workaround described in <a href="https://rockylinux.org/news/glibc-vulnerability-april-2024/">GLIBC Vulnerability on Servers Serving PHP</a> which explains a way on how to remove the problematic character set from glibc. Perform this procedure for every gconv-modules-extra.conf file that is available on your system.</p><p>PHP users on Windows are not affected.</p><p>Therefore, a new version of PHP will not be released for this vulnerability.</p></div></div><div><header class="title"><time datetime="2024-04-12T15:42:40+00:00">12 Apr 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.1.28. This is a security release.</p><p>All PHP 8.1 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.1.28 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.1.28">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-04-11T14:34:04+00:00">11 Apr 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.3.6. This is a security release.</p><p>All PHP 8.3 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.3.6 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.3.6">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-04-11T13:37:51+00:00">11 Apr 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.18. This is a security release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.18 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.18">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-03-14T21:02:45+00:00">14 Mar 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.3.4. This is a bug fix release.</p><p>All PHP 8.3 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.3.4 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.3.4">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-03-14T15:21:29+00:00">14 Mar 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.17. This is a bug fix release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.17 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.17">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-02-15T13:36:20-05:00">15 Feb 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.16. This is a bug fix release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.16 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.16">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-02-15T15:48:46+00:00">15 Feb 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.3.3. This is a bug fix release.</p><p>All PHP 8.3 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.3.3 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.3.3">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-01-18T15:35:45+00:00">18 Jan 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.15. This is a bug fix release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.15 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.15">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-01-18T14:47:41+00:00">18 Jan 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.3.2. This is a bug fix release.</p><p>All PHP 8.3 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.3.2 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.3.2">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2023-12-21T14:28:29-05:00">21 Dec 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.14. This is a bug fix release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.14 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.14">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2023-12-21T16:12:41+00:00">21 Dec 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.1.27. This is a bug fix release.</p><p>All PHP 8.1 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.1.27 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.1.27">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2023-12-21T07:48:56-08:00">21 Dec 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.3.1. This is a bug fix release.</p><p>All PHP 8.3 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.3.1 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.3.1">ChangeLog</a>.</p></div></div>]]></description>
      <link>https://www.php.net/index.php#2024-08-01-3</link>
      <guid>https://www.php.net/index.php#2024-08-01-3</guid>
      <pubDate>Thu, 01 Aug 2024 02:00:00 +0200</pubDate>
    </item>
    <item>
      <title><![CDATA[PHP OCI8 3.4 is available from PECL - Christopher Jones]]></title>
      <description><![CDATA[<div><div></div><p id="b0b2" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj">I’ve just released PHP OCI8 3.4 on <a class="af nd" href="http://pecl.php.net/package/oci8" rel="noopener ugc nofollow" target="_blank">PECL</a>. PHP is still active and going strong — and this is reflected in the download numbers for the <a class="af nd" href="https://www.php.net/manual/book.oci8.php" rel="noopener ugc nofollow" target="_blank">Oracle Database “OCI8” driver</a> for PHP, which had a 50% growth over the last year.</p><figure class="nh ni nj nk nl nm ne nf paragraph-image"><div role="button" tabindex="0" class="nn no fi np bg nq"><div class="ne nf ng"><picture><source srcset="https://miro.medium.com/v2/resize:fit:640/format:webp/0*Siqu4gMtlGbWmtC7 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/0*Siqu4gMtlGbWmtC7 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/0*Siqu4gMtlGbWmtC7 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/0*Siqu4gMtlGbWmtC7 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/0*Siqu4gMtlGbWmtC7 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/0*Siqu4gMtlGbWmtC7 1100w, https://miro.medium.com/v2/resize:fit:1400/format:webp/0*Siqu4gMtlGbWmtC7 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" type="image/webp" /><source data-testid="og" srcset="https://miro.medium.com/v2/resize:fit:640/0*Siqu4gMtlGbWmtC7 640w, https://miro.medium.com/v2/resize:fit:720/0*Siqu4gMtlGbWmtC7 720w, https://miro.medium.com/v2/resize:fit:750/0*Siqu4gMtlGbWmtC7 750w, https://miro.medium.com/v2/resize:fit:786/0*Siqu4gMtlGbWmtC7 786w, https://miro.medium.com/v2/resize:fit:828/0*Siqu4gMtlGbWmtC7 828w, https://miro.medium.com/v2/resize:fit:1100/0*Siqu4gMtlGbWmtC7 1100w, https://miro.medium.com/v2/resize:fit:1400/0*Siqu4gMtlGbWmtC7 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" /></picture></div></div><figcaption class="ns fe nt ne nf nu nv be b bf z dt">Photo by <a class="af nd" href="https://unsplash.com/@benofthenorth?utm_source=medium&amp;utm_medium=referral" rel="noopener ugc nofollow" target="_blank">Ben Griffiths</a> on <a class="af nd" href="https://unsplash.com/?utm_source=medium&amp;utm_medium=referral" rel="noopener ugc nofollow" target="_blank">Unsplash</a></figcaption></figure><p id="1959" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj">PHP OCI8 3.4 is a small iteration with one important change to better support external authentication, e.g with Oracle wallets, when using <code class="cw nw nx ny nz b">oci_pconnect()</code>. Other changes allow it to build with PHP 8.2 and PHP 8.3, and for the test suite to run cleanly with the improved database errors messages of Oracle Database 23ai.</p><p id="e9ea" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj">Install the new release in PHP 8.2 or 8.3 as a shared extension by executing:</p><pre class="nh ni nj nk nl oa nz ob bo oc ba bj">$<strong class="nz gu"> pecl install oci8</strong></pre><p id="7c3f" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj">and, when prompted, specify where to find Oracle Client libraries. On macOS ARM64 with the <a class="af nd" href="https://www.oracle.com/database/technologies/instant-client/macos-arm64-downloads.html" rel="noopener ugc nofollow" target="_blank">latest Instant Client</a> in <code class="cw nw nx ny nz b">$HOME/Downloads/instantclient_23_3</code>, my install log is like:</p><pre class="nh ni nj nk nl oa nz ob bo oc ba bj">$ <strong class="nz gu">pecl install oci8 </strong><br />downloading oci8-3.4.0.tgz ...<br />Starting to download oci8-3.4.0.tgz (194,647 bytes)<br />.........................................done: 194,647 bytes<br />13 source files, building<br />running: phpize<br />Configuring for:<br />PHP Api Version:         20230831<br />Zend Module Api No:      20230831<br />Zend Extension Api No:   420230831<br />Please provide the path to the ORACLE_HOME directory. Use 'instantclient,/path/to/instant/client/lib' if you're compiling with Oracle Instant Client [autodetect] : <strong class="nz gu">instantclient,/Users/cjones/Downloads/instantclient_23_3</strong>. . .Build process completed successfully<br />Installing '/Users/cjones/php/lib/php/extensions/no-debug-non-zts-20230831/oci8.so'<br />install ok: channel://pecl.php.net/oci8-3.4.0<br />configuration option "php_ini" is not set to php.ini location<br />You should add "extension=oci8.so" to php.ini</pre><p id="3111" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj">(Remember to use an absolute path without environment variables!)</p><p id="9534" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj">I then typically run <code class="cw nw nx ny nz b">php --ini</code> to find the location of the <code class="cw nw nx ny nz b">php.ini</code> file, and append <code class="cw nw nx ny nz b">extension=oci8.so</code> to that file.</p><p id="7ca7" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj">You can now check the driver is available:</p><pre class="nh ni nj nk nl oa nz ob bo oc ba bj">$ <strong class="nz gu">php --ri oci8</strong>oci8OCI8 Support =&gt; enabled<br />OCI8 DTrace Support =&gt; disabled<br />OCI8 Version =&gt; 3.4.0<br />Oracle Run-time Client Library Version =&gt; 23.3.0.23.9<br />Oracle Compile-time Instant Client Version =&gt; 23.3Directive =&gt; Local Value =&gt; Master Value<br />oci8.max_persistent =&gt; -1 =&gt; -1<br />oci8.persistent_timeout =&gt; -1 =&gt; -1<br />oci8.ping_interval =&gt; 60 =&gt; 60<br />oci8.privileged_connect =&gt; Off =&gt; Off<br />oci8.statement_cache_size =&gt; 20 =&gt; 20<br />oci8.default_prefetch =&gt; 100 =&gt; 100<br />oci8.old_oci_close_semantics =&gt; Off =&gt; Off<br />oci8.connection_class =&gt; no value =&gt; no value<br />oci8.events =&gt; Off =&gt; Off<br />oci8.prefetch_lob_size =&gt; 0 =&gt; 0Statistics =&gt;  <br />Active Persistent Connections =&gt; 0<br />Active Connections =&gt; 0</pre><p id="db55" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj">The OCI8 extension can be built with Oracle Client libraries from Oracle Database 11.2 or later. The Oracle Client libraries are in the free Oracle Instant Client from <a class="af nd" href="https://www.oracle.com/database/technologies/instant-client.html" rel="noopener ugc nofollow" target="_blank">www.oracle.com/database/technologies/instant-client.html</a>. They are also included in your database installation.</p><p id="d463" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj">Oracle’s standard cross-version connectivity applies. For example, PHP OCI8 linked with Oracle Client 19c can connect to Oracle Database 11.2 onward. See Oracle’s note <a class="af nd" href="https://support.oracle.com/knowledge/Oracle%20Cloud/207303_1.html" rel="noopener ugc nofollow" target="_blank">Client / Server Interoperability Support Matrix for Different Oracle Versions (ID 207303.1)</a> for details.</p><p id="d662" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj">PHP OCI8 3.4 also installs on the current PHP 8.4 Alpha release. If you have an older version of PHP, you will need to install an older driver, e.g.:</p><ul class=""><li id="bf92" class="mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc oj ok ol bj">Use <code class="cw nw nx ny nz b">pecl install oci8–3.2.1</code> to install for PHP 8.1.</li><li id="90c8" class="mf mg gt mh b mi om mk ml mm on mo mp mq oo ms mt mu op mw mx my oq na nb nc oj ok ol bj">Use <code class="cw nw nx ny nz b">pecl install oci8–3.0.1</code> to install for PHP 8.0.</li></ul><p id="df93" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj">If you need a reference for using PHP OCI8, check the second half of <a class="af nd" href="https://www.oracle.com/docs/tech/database/201212-ug-php-oracle.pdf" rel="noopener ugc nofollow" target="_blank">The Underground PHP and Oracle Manual</a> and, of course, the<a class="af nd" href="https://www.php.net/manual/book.oci8.php" rel="noopener ugc nofollow" target="_blank"> OCI8 Documentation</a>.</p></div>]]></description>
      <link>https://cjones-oracle.medium.com/php-oci8-3-4-is-available-from-pecl-33ff6c3f4442?source=rss-adc937c3a9d------2</link>
      <guid>https://cjones-oracle.medium.com/php-oci8-3-4-is-available-from-pecl-33ff6c3f4442?source=rss-adc937c3a9d------2</guid>
      <pubDate>Thu, 25 Jul 2024 05:23:00 +0200</pubDate>
    </item>
    <item>
      <title><![CDATA[python-oracledb 2.3 is even smaller on Linux - Christopher Jones]]></title>
      <description><![CDATA[<div><div></div><figure class="mi mj mk ml mm mn mf mg paragraph-image"><div role="button" tabindex="0" class="mo mp fi mq bg mr"><div class="mf mg mh"><picture><source srcset="https://miro.medium.com/v2/resize:fit:640/format:webp/0*8e1ymr_vWQGtPtsj 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/0*8e1ymr_vWQGtPtsj 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/0*8e1ymr_vWQGtPtsj 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/0*8e1ymr_vWQGtPtsj 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/0*8e1ymr_vWQGtPtsj 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/0*8e1ymr_vWQGtPtsj 1100w, https://miro.medium.com/v2/resize:fit:1400/format:webp/0*8e1ymr_vWQGtPtsj 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" type="image/webp" /><source data-testid="og" srcset="https://miro.medium.com/v2/resize:fit:640/0*8e1ymr_vWQGtPtsj 640w, https://miro.medium.com/v2/resize:fit:720/0*8e1ymr_vWQGtPtsj 720w, https://miro.medium.com/v2/resize:fit:750/0*8e1ymr_vWQGtPtsj 750w, https://miro.medium.com/v2/resize:fit:786/0*8e1ymr_vWQGtPtsj 786w, https://miro.medium.com/v2/resize:fit:828/0*8e1ymr_vWQGtPtsj 828w, https://miro.medium.com/v2/resize:fit:1100/0*8e1ymr_vWQGtPtsj 1100w, https://miro.medium.com/v2/resize:fit:1400/0*8e1ymr_vWQGtPtsj 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" /></picture></div></div><figcaption class="mt fe mu mf mg mv mw be b bf z dt">Photo by <a class="af mx" href="https://unsplash.com/@yassine_khalfalli?utm_source=medium&amp;utm_medium=referral" rel="noopener ugc nofollow" target="_blank">Yassine Khalfalli</a> on <a class="af mx" href="https://unsplash.com/?utm_source=medium&amp;utm_medium=referral" rel="noopener ugc nofollow" target="_blank">Unsplash</a></figcaption></figure><p id="528d" class="pw-post-body-paragraph my mz gt na b nb nc nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns nt nu nv gm bj">python-oracledb 2.3 has been released. My colleague @<a class="af mx" href="https://medium.com/@veronica.dumitriu" rel="noopener">Veronica Dumitriu</a> has posted the <a class="af mx" href="https://medium.com/@veronica.dumitriu/python-oracledb-2-3-has-been-released-2b3f99aec058" rel="noopener">release announcement</a>. There are lots of good improvements, such as support for the new <a class="af mx" href="https://python-oracledb.readthedocs.io/en/latest/user_guide/vector_data_type.html#binaryformat" rel="noopener ugc nofollow" target="_blank">VECTOR binary format</a> that is available in Oracle Database 23.5.</p><p id="e41d" class="pw-post-body-paragraph my mz gt na b nb nc nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns nt nu nv gm bj">One of the smaller (excuse the pun) enhancements is that the binary packages we put on <a class="af mx" href="https://pypi.org/project/oracledb/" rel="noopener ugc nofollow" target="_blank">PyPI</a> for Linux are now stripped.</p><p id="3bb7" class="pw-post-body-paragraph my mz gt na b nb nc nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns nt nu nv gm bj">With the previous python-oracledb 2.2 release the install footprint was:</p><pre class="nw nx ny nz oa ob oc od bo oe ba bj">$ du -sh /home/cjones/.local/lib/python3.11/site-packages/oracledb/<br />49M /home/cjones/.local/lib/python3.11/site-packages/oracledb/</pre><p id="2fca" class="pw-post-body-paragraph my mz gt na b nb nc nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns nt nu nv gm bj">Now with python-oracledb 2.3 :</p><pre class="nw nx ny nz oa ob oc od bo oe ba bj">$ du -sh /home/cjones/.local/lib/python3.11/site-packages/oracledb/<br />7.2M /home/cjones/.local/lib/python3.11/site-packages/oracledb/</pre><p id="68c6" class="pw-post-body-paragraph my mz gt na b nb nc nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns nt nu nv gm bj">For you micro-optimizers, we know every byte counts!</p><p id="9c4e" class="pw-post-body-paragraph my mz gt na b nb nc nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns nt nu nv gm bj">This small change brings Linux into parity with macOS, where the install footprint remains around the 11M mark.</p><h1 id="dad4" class="ol og gt be om on oo op oq or os ot ou ov ow ox oy oz pa pb pc pd pe pf pg ph bj">Installing or Upgrading python-oracledb</h1><p id="0e91" class="pw-post-body-paragraph my mz gt na b nb pi nd ne nf pj nh ni nj pk nl nm nn pl np nq nr pm nt nu nv gm bj">You can install or upgrade python-oracledb by running:</p><pre class="nw nx ny nz oa ob oc od bo oe ba bj">python -m pip install oracledb --upgrade</pre><p id="8206" class="pw-post-body-paragraph my mz gt na b nb nc nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns nt nu nv gm bj">The <code class="cw pn po pp oc b">pip</code> options <code class="cw pn po pp oc b">--proxy</code> and <code class="cw pn po pp oc b">--user</code> may be useful in some environments. See <a class="af mx" href="https://python-oracledb.readthedocs.io/en/latest/user_guide/installation.html" rel="noopener ugc nofollow" target="_blank">python-oracledb Installation</a> for details.</p><h1 id="bcad" class="ol og gt be om on oo op oq or os ot ou ov ow ox oy oz pa pb pc pd pe pf pg ph bj">Python-oracledb References</h1><p id="bf4d" class="pw-post-body-paragraph my mz gt na b nb pi nd ne nf pj nh ni nj pk nl nm nn pl np nq nr pm nt nu nv gm bj">Home page: <a class="af mx" href="https://oracle.github.io/python-oracledb/index.html" rel="noopener ugc nofollow" target="_blank">oracle.github.io/python-oracledb/index.html</a></p><p id="73c3" class="pw-post-body-paragraph my mz gt na b nb nc nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns nt nu nv gm bj">Installation instructions: <a class="af mx" href="https://python-oracledb.readthedocs.io/en/latest/user_guide/installation.html" rel="noopener ugc nofollow" target="_blank">python-oracledb.readthedocs.io/en/latest/installation.html</a></p><p id="28e8" class="pw-post-body-paragraph my mz gt na b nb nc nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns nt nu nv gm bj">Documentation: <a class="af mx" href="https://python-oracledb.readthedocs.io/en/latest/index.html" rel="noopener ugc nofollow" target="_blank">python-oracledb.readthedocs.io/en/latest/index.html</a></p><p id="080e" class="pw-post-body-paragraph my mz gt na b nb nc nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns nt nu nv gm bj">Release Notes: <a class="af mx" href="https://python-oracledb.readthedocs.io/en/latest/release_notes.html" rel="noopener ugc nofollow" target="_blank">python-oracledb.readthedocs.io/en/latest/release_notes.html</a></p><p id="8f82" class="pw-post-body-paragraph my mz gt na b nb nc nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns nt nu nv gm bj">Discussions: <a class="af mx" href="https://github.com/oracle/python-oracledb/discussions" rel="noopener ugc nofollow" target="_blank">github.com/oracle/python-oracledb/discussions</a></p><p id="fbaa" class="pw-post-body-paragraph my mz gt na b nb nc nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns nt nu nv gm bj">Issues: <a class="af mx" href="https://github.com/oracle/python-oracledb/issues" rel="noopener ugc nofollow" target="_blank">github.com/oracle/python-oracledb/issues</a></p><p id="aceb" class="pw-post-body-paragraph my mz gt na b nb nc nd ne nf ng nh ni nj nk nl nm nn no np nq nr ns nt nu nv gm bj">Source Code Repository: <a class="af mx" href="https://github.com/oracle/python-oracledb" rel="noopener ugc nofollow" target="_blank">github.com/oracle/python-oracledb</a></p></div>]]></description>
      <link>https://cjones-oracle.medium.com/python-oracledb-2-3-is-even-smaller-on-linux-adaded7294b9?source=rss-adc937c3a9d------2</link>
      <guid>https://cjones-oracle.medium.com/python-oracledb-2-3-is-even-smaller-on-linux-adaded7294b9?source=rss-adc937c3a9d------2</guid>
      <pubDate>Wed, 24 Jul 2024 08:48:00 +0200</pubDate>
    </item>
    <item>
      <title><![CDATA[PHP 8.4.0 Alpha 2 available for testing - PHP: Hypertext Preprocessor]]></title>
      <description><![CDATA[<div><header class="title"><time datetime="2024-07-18T13:30:46+00:00">18 Jul 2024</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the second testing release of PHP 8.4.0, Alpha 2. This continues the PHP 8.4 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php84">PHP Wiki</a>.</p><p>For source downloads of PHP 8.4.0 Alpha 2 please visit the <a href="https://downloads.php.net/~calvinb/">download page</a>.</p><p>Please carefully test this version and report any issues found in the <a href="https://github.com/php/php-src/issues">bug reporting system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.4.0alpha2/NEWS">NEWS</a> file, or the <a href="https://github.com/php/php-src/blob/php-8.4.0alpha2/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be Alpha 3, planned for 1 Aug 2024.</p><p>The signatures for the release can be found in <a href="https://gist.github.com/NattyNarwhal/74b55b8fcc6411ff8db05f87a6f41864">the manifest</a> or on <a href="https://qa.php.net/">the QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></div><div><header class="title"><time datetime="2024-07-05T13:22:12+00:00">05 Jul 2024</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the first testing release of PHP 8.4.0, Alpha 1. This starts the PHP 8.4 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php84">PHP Wiki</a>.</p><p>For source downloads of PHP 8.4.0 Alpha 1 please visit the <a href="https://downloads.php.net/~saki/">download page</a>.</p><p>Please carefully test this version and report any issues found using <a href="https://github.com/php/php-src/issues">the bug tracking system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.4.0alpha1/NEWS">NEWS</a> file, or the <a href="https://github.com/php/php-src/blob/php-8.4.0alpha1/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be Alpha 2, planned for 18 Jul 2024.</p><p>The signatures for the release can be found in the <a href="https://gist.github.com/SakiTakamachi/d3e32b780590319bee72d8402593a3ca">manifest</a> or on the <a href="https://qa.php.net/">QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></div><div><header class="title"><time datetime="2024-07-04T22:59:58+00:00">04 Jul 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.3.9. This is a bug fix release.</p><p>All PHP 8.3 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.3.9 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.3.9">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-07-04T14:43:24+00:00">04 Jul 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.21. This is a bug fix release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.21 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.21">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-06-06T14:56:47+00:00">06 Jun 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.20. This is a security release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.20 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.20">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-06-06T14:42:14+00:00">06 Jun 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.3.8. This is a security release.</p><p>All PHP 8.3 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.3.8 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.3.8">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-06-06T14:12:51+00:00">06 Jun 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.1.29. This is a security release.</p><p>All PHP 8.1 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.1.29 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.1.29">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-05-09T14:40:06+00:00">09 May 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.3.7. This is a bug fix release.</p><p>All PHP 8.3 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.3.7 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.3.7">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-05-09T13:48:33+00:00">09 May 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.19. This is a bug fix release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.19 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.19">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-04-24T18:40:29+00:00">24 Apr 2024</time>
</header><div class="newscontent"><p>EDIT 2024-04-25: Clarified when a PHP application is vulnerable to this bug.</p><p>Recently, a bug in <strong>glibc</strong> version 2.39 and older (<a href="https://nvd.nist.gov/vuln/detail/CVE-2024-2961">CVE-2024-2961</a>) was uncovered where a buffer overflow in character set conversions <strong>to</strong> the ISO-2022-CN-EXT character set can result in remote code execution.</p><p>This specific buffer overflow in glibc is exploitable through PHP, which exposes the iconv functionality of glibc to do character set conversions via the <a href="https://www.php.net/manual/en/function.iconv.php">iconv extension</a>. Although the bug is exploitable in the context of the PHP Engine, the bug is not in PHP. It is also not directly exploitable remotely.</p><p>The bug is exploitable, <strong>if and only if</strong>, the PHP application calls iconv <a href="https://www.php.net/manual/en/ref.iconv.php">functions</a> or <a href="https://www.php.net/manual/en/filters.convert.php#filters.convert.iconv">filters</a> with user-supplied character sets.</p><p>Applications are <strong>not</strong> vulnerable if:</p><ul><li>Glibc security updates from the distribution have been installed.</li>
<li>Or the iconv extension is not loaded.</li>
<li>Or the vulnerable character set has been removed from gconv-modules-extra.conf.</li>
<li>Or the application passes only specifically allowed character sets to iconv.</li>
</ul><p>Moreover, when using a user-supplied character set, it is good practice for applications to accept only specific charsets that have been explicitly allowed by the application. One example of how this can be done is by using an allow-list and the <a href="https://www.php.net/manual/en/function.array-search"><code>array_search()</code></a> function to check the encoding before passing it to iconv. For example: <code>array_search($charset, $allowed_list, true)</code></p><p>There are numerous reports online with titles like "Mitigating the iconv Vulnerability for PHP (CVE-2024-2961)" or "PHP Under Attack". These titles are misleading as this is <strong>not</strong> a bug in PHP itself.</p><p>If your PHP application is vulnerable, we first recommend to check if your Linux distribution has already published patched variants of glibc. <a href="https://security-tracker.debian.org/tracker/CVE-2024-2961">Debian</a>, CentOS, and others, have already done so, and please upgrade as soon as possible.</p><p>Once an update is available in glibc, updating that package on your Linux machine will be enough to alleviate the issue. You do not need to update PHP, as glibc is a dynamically linked library.</p><p>If your Linux distribution has not published a patched version of glibc, there is no fix for this issue. However, there exists a workaround described in <a href="https://rockylinux.org/news/glibc-vulnerability-april-2024/">GLIBC Vulnerability on Servers Serving PHP</a> which explains a way on how to remove the problematic character set from glibc. Perform this procedure for every gconv-modules-extra.conf file that is available on your system.</p><p>PHP users on Windows are not affected.</p><p>Therefore, a new version of PHP will not be released for this vulnerability.</p></div></div><div><header class="title"><time datetime="2024-04-12T15:42:40+00:00">12 Apr 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.1.28. This is a security release.</p><p>All PHP 8.1 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.1.28 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.1.28">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-04-11T14:34:04+00:00">11 Apr 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.3.6. This is a security release.</p><p>All PHP 8.3 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.3.6 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.3.6">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-04-11T13:37:51+00:00">11 Apr 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.18. This is a security release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.18 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.18">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-03-14T21:02:45+00:00">14 Mar 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.3.4. This is a bug fix release.</p><p>All PHP 8.3 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.3.4 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.3.4">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-03-14T15:21:29+00:00">14 Mar 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.17. This is a bug fix release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.17 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.17">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-02-15T13:36:20-05:00">15 Feb 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.16. This is a bug fix release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.16 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.16">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-02-15T15:48:46+00:00">15 Feb 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.3.3. This is a bug fix release.</p><p>All PHP 8.3 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.3.3 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.3.3">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-01-18T15:35:45+00:00">18 Jan 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.15. This is a bug fix release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.15 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.15">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-01-18T14:47:41+00:00">18 Jan 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.3.2. This is a bug fix release.</p><p>All PHP 8.3 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.3.2 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.3.2">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2023-12-21T14:28:29-05:00">21 Dec 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.14. This is a bug fix release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.14 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.14">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2023-12-21T16:12:41+00:00">21 Dec 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.1.27. This is a bug fix release.</p><p>All PHP 8.1 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.1.27 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.1.27">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2023-12-21T07:48:56-08:00">21 Dec 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.3.1. This is a bug fix release.</p><p>All PHP 8.3 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.3.1 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.3.1">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2023-11-23T18:24:51+00:00">23 Nov 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.1.26. This is a bug fix release.</p><p>All PHP 8.1 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.1.26 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.1.26">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2023-11-23T15:43:03+00:00">23 Nov 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.3.0. This release marks the latest minor release of the PHP language.</p><p>PHP 8.3 comes with numerous improvements and new features such as:</p><p>For source downloads of PHP 8.3.0 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.3.0">ChangeLog</a>.</p><p>The <a href="https://php.net/manual/en/migration83.php">migration guide</a> is available in the PHP Manual. Please consult it for the detailed list of new features and backward incompatible changes.</p><p>Kudos to all the contributors and supporters!</p></div></div><div><header class="title"><time datetime="2023-11-23T12:24:42+00:00">23 Nov 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.13. This is a bug fix release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.13 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.13">ChangeLog</a>.</p></div></div>]]></description>
      <link>https://www.php.net/index.php#2024-07-18-1</link>
      <guid>https://www.php.net/index.php#2024-07-18-1</guid>
      <pubDate>Thu, 18 Jul 2024 02:00:00 +0200</pubDate>
    </item>
    <item>
      <title><![CDATA[Installation Cheatsheet for Oracle Instant Client on Oracle Linux - Christopher Jones]]></title>
      <description><![CDATA[<div><div></div><p id="9d4b" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj">Wondering how to install Oracle Instant Client on Oracle Linux from Oracle’s <a class="af nd" href="https://yum.oracle.com/" rel="noopener ugc nofollow" target="_blank">yum</a> repository? This is what you need to know.</p><figure class="nh ni nj nk nl nm ne nf paragraph-image"><div role="button" tabindex="0" class="nn no fi np bg nq"><div class="ne nf ng"><picture><source srcset="https://miro.medium.com/v2/resize:fit:640/format:webp/0*oRSWFDHPOU1AGiF8 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/0*oRSWFDHPOU1AGiF8 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/0*oRSWFDHPOU1AGiF8 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/0*oRSWFDHPOU1AGiF8 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/0*oRSWFDHPOU1AGiF8 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/0*oRSWFDHPOU1AGiF8 1100w, https://miro.medium.com/v2/resize:fit:1400/format:webp/0*oRSWFDHPOU1AGiF8 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" type="image/webp" /><source data-testid="og" srcset="https://miro.medium.com/v2/resize:fit:640/0*oRSWFDHPOU1AGiF8 640w, https://miro.medium.com/v2/resize:fit:720/0*oRSWFDHPOU1AGiF8 720w, https://miro.medium.com/v2/resize:fit:750/0*oRSWFDHPOU1AGiF8 750w, https://miro.medium.com/v2/resize:fit:786/0*oRSWFDHPOU1AGiF8 786w, https://miro.medium.com/v2/resize:fit:828/0*oRSWFDHPOU1AGiF8 828w, https://miro.medium.com/v2/resize:fit:1100/0*oRSWFDHPOU1AGiF8 1100w, https://miro.medium.com/v2/resize:fit:1400/0*oRSWFDHPOU1AGiF8 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" /></picture></div></div><figcaption class="ns fe nt ne nf nu nv be b bf z dt">A non-cheating sheet — Photo by <a class="af nd" href="https://unsplash.com/@svalenas?utm_source=medium&amp;utm_medium=referral" rel="noopener ugc nofollow" target="_blank">Sergiu Vălenaș</a> on <a class="af nd" href="https://unsplash.com/?utm_source=medium&amp;utm_medium=referral" rel="noopener ugc nofollow" target="_blank">Unsplash</a></figcaption></figure><p id="6e7b" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj"><a class="af nd" href="https://www.oracle.com/database/technologies/instant-client.html" rel="noopener ugc nofollow" target="_blank">Oracle Instant Client</a> enables development and deployment of applications that connect to Oracle Database, either on-premise or in the Cloud. The Instant Client libraries provide the necessary network connectivity and advanced data features to make full use of Oracle Database. The libraries are used by the Oracle APIs of popular languages and environments including Python, Node.js, Go, PHP and Ruby, as well as providing access for Oracle Call Interface (OCI), Oracle C++ Call Interface (OCCI), JDBC OCI, ODBC and Pro*C applications. Tools included in Instant Client, such as SQL*Plus, SQL*Loader and Oracle Data Pump, provide quick and convenient data access.</p><p id="7d69" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj">Oracle Instant Client is available on many platforms as simple zip <a class="af nd" href="https://www.oracle.com/database/technologies/instant-client/downloads.html" rel="noopener ugc nofollow" target="_blank">downloads</a> from Oracle. This post shows how the packages can also be installed using Oracle Linux yum repositories.</p><h1 id="e17f" class="nw nx gt be ny nz oa ob oc od oe of og oh oi oj ok ol om on oo op oq or os ot bj">Packages</h1><p id="db7d" class="pw-post-body-paragraph mf mg gt mh b mi ou mk ml mm ov mo mp mq ow ms mt mu ox mw mx my oy na nb nc gm bj"><strong class="mh gu">18c &amp; 19c OL7:</strong></p><ul class=""><li id="70d6" class="mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc oz pa pb bj"><a class="af nd" href="https://yum.oracle.com/repo/OracleLinux/OL7/oracle/instantclient/x86_64/" rel="noopener ugc nofollow" target="_blank">https://yum.oracle.com/repo/OracleLinux/OL7/oracle/instantclient/x86_64/</a></li><li id="7187" class="mf mg gt mh b mi pc mk ml mm pd mo mp mq pe ms mt mu pf mw mx my pg na nb nc oz pa pb bj"><a class="af nd" href="https://yum.oracle.com/repo/OracleLinux/OL7/oracle/instantclient/aarch64/" rel="noopener ugc nofollow" target="_blank">https://yum.oracle.com/repo/OracleLinux/OL7/oracle/instantclient/aarch64/</a></li></ul><pre class="nh ni nj nk nl ph pi pj bo pk ba bj">sudo yum install oracle-release-el7<br />sudo yum install oracle-instantclient19.23-basic</pre><p id="7c8c" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj"><strong class="mh gu">19c OL8:</strong></p><ul class=""><li id="3ab0" class="mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc oz pa pb bj"><a class="af nd" href="https://yum.oracle.com/repo/OracleLinux/OL8/oracle/instantclient/x86_64/" rel="noopener ugc nofollow" target="_blank">https://yum.oracle.com/repo/OracleLinux/OL8/oracle/instantclient/x86_64/</a></li><li id="e0ba" class="mf mg gt mh b mi pc mk ml mm pd mo mp mq pe ms mt mu pf mw mx my pg na nb nc oz pa pb bj"><a class="af nd" href="https://yum.oracle.com/repo/OracleLinux/OL8/oracle/instantclient/aarch64/" rel="noopener ugc nofollow" target="_blank">https://yum.oracle.com/repo/OracleLinux/OL8/oracle/instantclient/aarch64/</a></li></ul><pre class="nh ni nj nk nl ph pi pj bo pk ba bj">sudo dnf install -y oracle-release-el8<br />sudo dnf install -y oracle-instantclient19.23-basic</pre><p id="6a92" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj"><strong class="mh gu">19c OL9:</strong></p><ul class=""><li id="e85b" class="mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc oz pa pb bj"><a class="af nd" href="https://yum.oracle.com/repo/OracleLinux/OL9/oracle/instantclient/x86_64/" rel="noopener ugc nofollow" target="_blank">https://yum.oracle.com/repo/OracleLinux/OL9/oracle/instantclient/x86_64/</a></li></ul><pre class="nh ni nj nk nl ph pi pj bo pk ba bj">sudo dnf install oracle-instantclient-release-el9<br />sudo dnf install oracle-instantclient19.19-basic</pre><p id="e761" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj"><strong class="mh gu">21c OL7:</strong></p><ul class=""><li id="d75f" class="mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc oz pa pb bj"><a class="af nd" href="https://yum.oracle.com/repo/OracleLinux/OL7/oracle/instantclient21/x86_64/" rel="noopener ugc nofollow" target="_blank">https://yum.oracle.com/repo/OracleLinux/OL7/oracle/instantclient21/x86_64/</a></li></ul><pre class="nh ni nj nk nl ph pi pj bo pk ba bj">sudo yum install oracle-instantclient-release-el7<br />sudo yum install oracle-instantclient-basic</pre><p id="1f9a" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj"><strong class="mh gu">21c OL8:</strong></p><ul class=""><li id="e0a4" class="mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc oz pa pb bj"><a class="af nd" href="https://yum.oracle.com/repo/OracleLinux/OL8/oracle/instantclient21/x86_64/" rel="noopener ugc nofollow" target="_blank">https://yum.oracle.com/repo/OracleLinux/OL8/oracle/instantclient21/x86_64/</a></li></ul><pre class="nh ni nj nk nl ph pi pj bo pk ba bj">sudo dnf install oracle-instantclient-release-el8<br />sudo dnf install oracle-instantclient-basic</pre><p id="8bbd" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj"><strong class="mh gu">23ai OL8:</strong></p><ul class=""><li id="9262" class="mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc oz pa pb bj"><a class="af nd" href="https://yum.oracle.com/repo/OracleLinux/OL8/oracle/instantclient23/x86_64/" rel="noopener ugc nofollow" target="_blank">https://yum.oracle.com/repo/OracleLinux/OL8/oracle/instantclient23/x86_64/</a></li></ul><pre class="nh ni nj nk nl ph pi pj bo pk ba bj">sudo dnf install oracle-instantclient-release-23ai-el8<br />sudo dnf install oracle-instantclient-basic</pre><p id="c9b3" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj"><strong class="mh gu">23ai OL9:</strong></p><ul class=""><li id="b6f0" class="mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc oz pa pb bj"><a class="af nd" href="https://yum.oracle.com/repo/OracleLinux/OL9/oracle/instantclient23/x86_64/" rel="noopener ugc nofollow" target="_blank">https://yum.oracle.com/repo/OracleLinux/OL9/oracle/instantclient23/x86_64/</a></li></ul><pre class="nh ni nj nk nl ph pi pj bo pk ba bj">sudo dnf install oracle-instantclient-release-23ai-el9<br />sudo dnf install oracle-instantclient-basic</pre><h2 id="9609" class="pq nx gt be ny pr ps dx oc pt pu dz og mq pv pw px mu py pz qa my qb qc qd qe bj">Notes</h2><p id="4c6b" class="pw-post-body-paragraph mf mg gt mh b mi ou mk ml mm ov mo mp mq ow ms mt mu ox mw mx my oy na nb nc gm bj">For 18c and 19c, you need to explicitly give the RU (the ‘Release Update’ patch number) in the filename when installing. To upgrade, you need to remove the old package and install the new one. Please check the repos and keep up to date!</p><p id="b39f" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj">From 21c, any <code class="cw qf qg qh pi b">yum</code> or <code class="cw qf qg qh pi b">dnf update</code> will automatically pull in the latest RU. If<br />you need to prevent an update, then use <code class="cw qf qg qh pi b">versionlock</code>, as discussed in the<br /><a class="af nd" href="https://docs.oracle.com/en/database/oracle/oracle-database/23/lacli/install-instant-client-using-rpm.html#GUID-2E81E2AE-E94C-413F-99B2-AE9A3949F05D" rel="noopener ugc nofollow" target="_blank">Installing Oracle Instant Client Using RPMs documentation</a>, e.g :</p><pre class="nh ni nj nk nl ph pi pj bo pk ba bj">dnf versionlock oracle-instantclient-release-23ai-el8</pre><h1 id="c3dc" class="nw nx gt be ny nz oa ob oc od oe of og oh oi oj ok ol om on oo op oq or os ot bj"><strong class="al">Containers</strong></h1><p id="01e3" class="pw-post-body-paragraph mf mg gt mh b mi ou mk ml mm ov mo mp mq ow ms mt mu ox mw mx my oy na nb nc gm bj"><strong class="mh gu">Sample Dockerfiles:</strong></p><ul class=""><li id="144f" class="mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc oz pa pb bj"><a class="af nd" href="https://github.com/oracle/docker-images/tree/main/OracleInstantClient" rel="noopener ugc nofollow" target="_blank">https://github.com/oracle/docker-images/tree/main/OracleInstantClient</a></li></ul><p id="c224" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj"><strong class="mh gu">Prebuilt containers — with Basic, SQL*Plus, and SDK packages:</strong></p><ul class=""><li id="ceb5" class="mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc oz pa pb bj"><a class="af nd" href="https://github.com/oracle/docker-images/pkgs/container/oraclelinux7-instantclient" rel="noopener ugc nofollow" target="_blank">https://github.com/oracle/docker-images/pkgs/container/oraclelinux7-instantclient</a></li><li id="af76" class="mf mg gt mh b mi pc mk ml mm pd mo mp mq pe ms mt mu pf mw mx my pg na nb nc oz pa pb bj"><a class="af nd" href="https://github.com/oracle/docker-images/pkgs/container/oraclelinux8-instantclient" rel="noopener ugc nofollow" target="_blank">https://github.com/oracle/docker-images/pkgs/container/oraclelinux8-instantclient</a></li><li id="3e2a" class="mf mg gt mh b mi pc mk ml mm pd mo mp mq pe ms mt mu pf mw mx my pg na nb nc oz pa pb bj"><a class="af nd" href="https://github.com/oracle/docker-images/pkgs/container/oraclelinux9-instantclient" rel="noopener ugc nofollow" target="_blank">https://github.com/oracle/docker-images/pkgs/container/oraclelinux9-instantclient</a></li></ul><p id="7d54" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj">Use like:</p><pre class="nh ni nj nk nl ph pi pj bo pk ba bj">docker pull ghcr.io/oracle/oraclelinux9-instantclient:23</pre><h1 id="18aa" class="nw nx gt be ny nz oa ob oc od oe of og oh oi oj ok ol om on oo op oq or os ot bj">Instant Client Installation Documentation</h1><p id="9ea9" class="pw-post-body-paragraph mf mg gt mh b mi ou mk ml mm ov mo mp mq ow ms mt mu ox mw mx my oy na nb nc gm bj">Oracle Linux installation instructions: <a class="af nd" href="https://yum.oracle.com/oracle-instant-client.html" rel="noopener ugc nofollow" target="_blank">https://yum.oracle.com/oracle-instant-client.html</a></p><p id="b5e3" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj">Oracle Client 23ai installation documentation: <a class="af nd" href="https://docs.oracle.com/en/database/oracle/oracle-database/23/lacli/instant-client-install-linux.html#GUID-CD3C72C6-110E-453A-8B69-2961D37EB70B" rel="noopener ugc nofollow" target="_blank">Installing Oracle Instant Client Packages</a></p><p id="fae9" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj">Oracle Client 21c installation documentation <a class="af nd" href="https://docs.oracle.com/en/database/oracle/oracle-database/21/lacli/instant-client-install-linux.html#GUID-CD3C72C6-110E-453A-8B69-2961D37EB70B" rel="noopener ugc nofollow" target="_blank">Installing Oracle Instant Client Packages</a></p></div>]]></description>
      <link>https://medium.com/oracledevs/installation-cheatsheet-for-oracle-instant-client-on-oracle-linux-b035b7bbebf2?source=rss-adc937c3a9d------2</link>
      <guid>https://medium.com/oracledevs/installation-cheatsheet-for-oracle-instant-client-on-oracle-linux-b035b7bbebf2?source=rss-adc937c3a9d------2</guid>
      <pubDate>Sat, 13 Jul 2024 01:32:00 +0200</pubDate>
    </item>
    <item>
      <title><![CDATA[The best of Relational and JSON — at the same time - Christopher Jones]]></title>
      <description><![CDATA[<div><div></div><p id="90d5" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj">Oracle Database 23ai JSON-Relational Duality Views allow data to be stored as rows in tables to provide the benefits of SQL access in a relational model, while also allowing read and write access as JSON documents to the <strong class="mh gu">exact same data</strong>. This blog shows how to use the new views in Python.</p><figure class="ng nh ni nj nk nl nd ne paragraph-image"><div role="button" tabindex="0" class="nm nn fi no bg np"><div class="nd ne nf"><picture><source srcset="https://miro.medium.com/v2/resize:fit:640/format:webp/0*dKZDi_qeve7jTq27 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/0*dKZDi_qeve7jTq27 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/0*dKZDi_qeve7jTq27 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/0*dKZDi_qeve7jTq27 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/0*dKZDi_qeve7jTq27 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/0*dKZDi_qeve7jTq27 1100w, https://miro.medium.com/v2/resize:fit:1400/format:webp/0*dKZDi_qeve7jTq27 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" type="image/webp" /><source data-testid="og" srcset="https://miro.medium.com/v2/resize:fit:640/0*dKZDi_qeve7jTq27 640w, https://miro.medium.com/v2/resize:fit:720/0*dKZDi_qeve7jTq27 720w, https://miro.medium.com/v2/resize:fit:750/0*dKZDi_qeve7jTq27 750w, https://miro.medium.com/v2/resize:fit:786/0*dKZDi_qeve7jTq27 786w, https://miro.medium.com/v2/resize:fit:828/0*dKZDi_qeve7jTq27 828w, https://miro.medium.com/v2/resize:fit:1100/0*dKZDi_qeve7jTq27 1100w, https://miro.medium.com/v2/resize:fit:1400/0*dKZDi_qeve7jTq27 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" /></picture></div></div><figcaption class="nr fe ns nd ne nt nu be b bf z dt">Photo by <a class="af nv" href="https://unsplash.com/@pietrozj?utm_source=medium&amp;utm_medium=referral" rel="noopener ugc nofollow" target="_blank">Pietro Jeng</a> on <a class="af nv" href="https://unsplash.com/?utm_source=medium&amp;utm_medium=referral" rel="noopener ugc nofollow" target="_blank">Unsplash</a></figcaption></figure><p id="6add" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj">The relational model is great: you can avoid data duplication; data consistency is guaranteed; and you have access via a very powerful, very efficient language — SQL. But, for developers, the requirement to define a relational schema — to decide on tables, columns and data types — before beginning to code is a chore. It’s not easy to predict future uses for the system, some of which may be difficult with the chosen schema.</p><p id="6cde" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj">This is why you love JSON. A JSON object can contain all the information for one use case without the need to use SQL to join tables. Access is via a simple query, or a single call to a database API. JSON is schema-flexible so, as your use cases evolve over the lifetime of a system, you can easily modify applications. But there are drawbacks: a single hierarchy may only allow a few use cases. Data can end up being duplicated, which affects not just space but makes it very hard to keep consistent. Optimization is harder. So what appears to be a simple model can end up causing long term complexity.</p><p id="f21a" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj">This is where Oracle Database 23ai JSON-Relational Duality Views are an outright game changer — not a phrase I use lightly. These duality views build on Oracle Database’s long history of JSON support and longer history with the relational model.</p><p id="a77f" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj">Let’s start by creating two relational tables:</p><pre class="ng nh ni nj nk nw nx ny bo nz ba bj">drop table if exists AuthorTab;<br />drop table if exists BookTab;create table AuthorTab (<br />    AuthorId number generated by default on null as identity primary key,<br />    AuthorName varchar2(100)<br />);create table BookTab (<br />    BookId number generated by default on null as identity primary key,<br />    BookTitle varchar2(100),<br />    AuthorId number references AuthorTab (AuthorId)<br />);insert into AuthorTab values (1, 'Isabel M. Rich');<br />insert into AuthorTab values (2, 'Bobbie Cool');<br />insert into AuthorTab values (3, 'Charlie Shore');<br />insert into BookTab values (1, 'The Mysterious Dog', 1);<br />insert into BookTab values (2, 'The Mysterious Pony', 1);<br />insert into BookTab values (3, 'The Mysterious Tiger', 1);<br />insert into BookTab values (4, 'Self Help for Programmers', 2);<br />insert into BookTab values (5, 'More Self Help for Programmers', 2);<br />insert into BookTab values (6, 'Travel Guide Volume I', 3);<br />insert into BookTab values (7, 'Travel Guide Volume II', 3);commit;</pre><p id="971b" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj">These can obviously be accessed via relational SELECT, INSERT etc statements which are trivial to execute in Python using <a class="af nv" href="https://pypi.org/project/oracledb/" rel="noopener ugc nofollow" target="_blank">python-oracledb</a>, for example:</p><pre class="ng nh ni nj nk nw nx ny bo nz ba bj">import oracledbconnection = oracledb.connect(user="cj", password="MySecret", <br />                              dsn="localhost/orclpdb1")with connection.cursor() as cursor:<br />    sql = """select AuthorName, BookTitle<br />             from AuthorTab, BookTab<br />             where AuthorTab.AuthorId = BookTab.AuthorId"""<br />    for r in cursor.execute(sql):<br />        print(r)</pre><p id="f83e" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj">The output lists the authors and their books:</p><pre class="ng nh ni nj nk nw nx ny bo nz ba bj">('Isabel M. Rich', 'The Mysterious Dog')<br />('Isabel M. Rich', 'The Mysterious Pony')<br />('Isabel M. Rich', 'The Mysterious Tiger')<br />('Bobbie Cool', 'Self Help for Programmers')<br />('Bobbie Cool', 'More Self Help for Programmers')<br />('Charlie Shore', 'Travel Guide Volume I')<br />('Charlie Shore', 'Travel Guide Volume II')</pre><p id="1f22" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj">The fun is to create a duality view. In your SQL editor run:</p><pre class="ng nh ni nj nk nw nx ny bo nz ba bj">create or replace json relational duality view BookDV as<br />BookTab @insert @update @delete<br />{<br />   _id: BookId,<br />   book_title: BookTitle,<br />   author: AuthorTab @insert @update<br />   {<br />       author_id: AuthorId,<br />       author_name: AuthorName<br />   }<br />};</pre><p id="a1d6" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj">This creates a view that is accessible using JSON. The syntax shown here is <a class="af nv" href="https://docs.oracle.com/en/database/oracle/oracle-database/23/jsnvu/graphql-language-used-json-relational-duality-views.html#GUID-0484D22D-AF10-4B2A-9D96-D4206DB23D0B" rel="noopener ugc nofollow" target="_blank">GraphQL</a>, letting the database work out relations. Alternatively you could use a simplified SQL syntax — see the documentation.</p><p id="1686" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj">With the <code class="cw og oh oi nx b">BookDV</code> duality view created, you can access it as a document or by using the power of python-oracledb and Oracle Database’s JSON features. For example, to find the book with ID of 1 using <a class="af nv" href="https://docs.oracle.com/en/database/oracle/oracle-database/23/adjsn/simple-dot-notation-access-to-json-data.html#GUID-7249417B-A337-4854-8040-192D5CEFD576" rel="noopener ugc nofollow" target="_blank">simple dot-notation access</a> you can access the special column DATA:</p><pre class="ng nh ni nj nk nw nx ny bo nz ba bj">sql = """select b.data.book_title, b.data.author.author_name<br />	 from BookDV b<br />         where b.data."_id" = :1"""<br />for r in cursor.execute(sql, [1]):<br />    print(r)</pre><p id="b925" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj">This shows:</p><pre class="ng nh ni nj nk nw nx ny bo nz ba bj">('The Mysterious Dog', 'Isabel M. Rich')</pre><p id="a53a" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj">To access the duality view with simple API calls, use Oracle Database’s <a class="af nv" href="https://python-oracledb.readthedocs.io/en/latest/user_guide/soda.html" rel="noopener ugc nofollow" target="_blank">SODA</a> functionality (this requires python-oracledb be run in <a class="af nv" href="https://python-oracledb.readthedocs.io/en/latest/user_guide/initialization.html#enabling-python-oracledb-thick-mode" rel="noopener ugc nofollow" target="_blank">Thick mode</a>). For example, to run a query-by-example on the view, open it as a collection:</p><pre class="ng nh ni nj nk nw nx ny bo nz ba bj">soda = connection.getSodaDatabase()<br />collection = soda.openCollection('BOOKDV')qbe = {'book_title': {'$like': 'The%'}}<br />for doc in collection.find().filter(qbe).getDocuments():<br />    content = doc.getContent()<br />    print(content["book_title"])</pre><p id="6348" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj">This prints the matching book titles:</p><pre class="ng nh ni nj nk nw nx ny bo nz ba bj">The Mysterious Dog<br />The Mysterious Pony<br />The Mysterious Tiger</pre><p id="b42c" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj">The real magic of duality views comes when you need to update or insert new data. You can use the view for that too, for example with an <code class="cw og oh oi nx b">INSERT</code> statement:</p><pre class="ng nh ni nj nk nw nx ny bo nz ba bj">data = dict(<br />    _id=101,<br />    book_title="Cooking at Home",<br />    author=dict(author_id=201, author_name="Dave Smith"),<br />)<br />inssql = "insert into BookDV values (:1)"<br />cursor.setinputsizes(oracledb.DB_TYPE_JSON)<br />cursor.execute(inssql, [data])<br />connection.commit()</pre><p id="c549" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj">The duality view understands the relationship between the tables and both tables get updated, as can be seen with a canonical query in your SQL editor:</p><pre class="ng nh ni nj nk nw nx ny bo nz ba bj">SQL&gt; select BookId, BookTitle, AuthorName, AuthorTab.Authorid<br />  2  from AuthorTab, BookTab<br />  3  where AuthorTab.AuthorId = BookTab.AuthorId;BOOKID BOOKTITLE                      AUTHORNAME             AUTHORID<br />---------- ------------------------------ -------------------- ----------<br />         1 The Mysterious Dog             Isabel M. Rich                1<br />         2 The Mysterious Pony            Isabel M. Rich                1<br />         3 The Mysterious Tiger           Isabel M. Rich                1<br />         4 Self Help for Programmers      Bobbie Cool                   2<br />         5 More Self Help for Programmers Bobbie Cool                   2<br />         6 Travel Guide Volume I          Charlie Shore                 3<br />         7 Travel Guide Volume II         Charlie Shore                 3<br />       101 Cooking at Home                Dave Smith                  201</pre><p id="ce0e" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj">Simple! You can also update the view via SODA, if that is your preferred style.</p><p id="fba7" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj">A runnable example is in <a class="af nv" href="https://github.com/oracle/python-oracledb/blob/main/samples/json_duality.py" rel="noopener ugc nofollow" target="_blank">json_duality.py</a></p><h1 id="af30" class="oj ob gt be ok ol om on oo op oq or os ot ou ov ow ox oy oz pa pb pc pd pe pf bj">Conclusion</h1><p id="fd01" class="pw-post-body-paragraph mf mg gt mh b mi pg mk ml mm ph mo mp mq pi ms mt mu pj mw mx my pk na nb nc gm bj">Oracle Database 23ai JSON-Relational Duality Views marry the best of the relational models with the best of JSON. Both JSON and SQL can be used in many Oracle Database language drivers, giving you a wide choice of client technologies and data models.</p><p id="573d" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj">See the <a class="af nv" href="https://www.oracle.com/pls/topic/lookup?ctx=dblatest&amp;id=JSNVU" rel="noopener ugc nofollow" target="_blank">JSON-Relational Duality Developer’s Guide</a> for more information.</p><p id="40d5" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj">Also, I recommend you join my colleague Beda Hammerschmidt for his free <a class="af nv" href="https://asktom.oracle.com/ords/r/tech/catalog/series-landing-page?p5_series_id=332641644178872677514939961789475629634" rel="noopener ugc nofollow" target="_blank">JSON in Oracle Database Office Hours</a> series. You can watch recordings of previous presentations, or sign-up for upcoming live ones.</p><p id="e77d" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj">And finally never forget that Oracle Database is a database with many models, including: <a class="af nv" href="https://docs.oracle.com/en/database/oracle/oracle-database/23/adjsn/index.html" rel="noopener ugc nofollow" target="_blank">JSON</a>, <a class="af nv" href="https://docs.oracle.com/en/database/oracle/simple-oracle-document-access/" rel="noopener ugc nofollow" target="_blank">NoSQL</a>, <a class="af nv" href="https://docs.oracle.com/en/database/oracle/property-graph/index.html" rel="noopener ugc nofollow" target="_blank">Graph</a>, <a class="af nv" href="https://docs.oracle.com/en/database/oracle/oracle-database/23/adobj/index.html" rel="noopener ugc nofollow" target="_blank">Object</a>, <a class="af nv" href="https://docs.oracle.com/en/database/oracle/oracle-database/23/spatl/index.html" rel="noopener ugc nofollow" target="_blank">Spatial</a>, <a class="af nv" href="https://docs.oracle.com/en/database/oracle/oracle-database/23/adxdb/index.html" rel="noopener ugc nofollow" target="_blank">XML</a>, <a class="af nv" href="https://docs.oracle.com/en/database/oracle/oracle-database/23/vecse/index.html" rel="noopener ugc nofollow" target="_blank">Vectors</a>, and <a class="af nv" href="https://docs.oracle.com/en/database/oracle/oracle-database/23/sqlrf/index.html" rel="noopener ugc nofollow" target="_blank">Relational</a>. This gives you enormous power, and lets you keep all your data safe in the one system.</p><h1 id="a51f" class="oj ob gt be ok ol om on oo op oq or os ot ou ov ow ox oy oz pa pb pc pd pe pf bj">References</h1><ul class=""><li id="bf05" class="mf mg gt mh b mi pg mk ml mm ph mo mp mq pi ms mt mu pj mw mx my pk na nb nc pl pm pn bj">Documentation: <a class="af nv" href="https://www.oracle.com/pls/topic/lookup?ctx=dblatest&amp;id=JSNVU" rel="noopener ugc nofollow" target="_blank">JSON-Relational Duality Developer’s Guide</a></li><li id="c40f" class="mf mg gt mh b mi po mk ml mm pp mo mp mq pq ms mt mu pr mw mx my ps na nb nc pl pm pn bj">Oracle Forum: <a class="af nv" href="https://forums.oracle.com/ords/apexds/domain/dev-community/category/oracle_rest_data_services" rel="noopener ugc nofollow" target="_blank">ORDS, SODA &amp; JSON in the Database</a></li><li id="7fde" class="mf mg gt mh b mi po mk ml mm pp mo mp mq pq ms mt mu pr mw mx my ps na nb nc pl pm pn bj">Software: <a class="af nv" href="https://pypi.org/project/oracledb/" rel="noopener ugc nofollow" target="_blank">python-oracledb driver</a></li><li id="5bf9" class="mf mg gt mh b mi po mk ml mm pp mo mp mq pq ms mt mu pr mw mx my ps na nb nc pl pm pn bj">Software: <a class="af nv" href="https://www.oracle.com/database/technologies/oracle-database-software-downloads.html" rel="noopener ugc nofollow" target="_blank">Oracle Database 23ai</a></li></ul></div>]]></description>
      <link>https://medium.com/oracledevs/the-best-of-relational-and-json-at-the-same-time-62f9ba291c98?source=rss-adc937c3a9d------2</link>
      <guid>https://medium.com/oracledevs/the-best-of-relational-and-json-at-the-same-time-62f9ba291c98?source=rss-adc937c3a9d------2</guid>
      <pubDate>Thu, 11 Jul 2024 08:26:00 +0200</pubDate>
    </item>
    <item>
      <title><![CDATA[Using the %ROWTYPE attribute with python-oracledb - Christopher Jones]]></title>
      <description><![CDATA[<div><div></div><p id="5089" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj">When using Python to interact with Oracle Database PL/SQL stored procedures, you may encounter PL/SQL code that uses the <a class="af nd" href="https://www.oracle.com/pls/topic/lookup?ctx=dblatest&amp;id=GUID-4E0B9FE2-909D-444A-9B4A-E0243B7FCB99" rel="noopener ugc nofollow" target="_blank">%ROWTYPE attribute</a>. This is used to declare a record that represents either a full or partial row of a database table or view. This blog post shows how to use %ROWTYPE in python-oracledb.</p><figure class="nh ni nj nk nl nm ne nf paragraph-image"><div role="button" tabindex="0" class="nn no fi np bg nq"><div class="ne nf ng"><picture><source srcset="https://miro.medium.com/v2/resize:fit:640/format:webp/0*lVGMidsSsVJQTqpx 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/0*lVGMidsSsVJQTqpx 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/0*lVGMidsSsVJQTqpx 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/0*lVGMidsSsVJQTqpx 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/0*lVGMidsSsVJQTqpx 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/0*lVGMidsSsVJQTqpx 1100w, https://miro.medium.com/v2/resize:fit:1400/format:webp/0*lVGMidsSsVJQTqpx 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" type="image/webp" /><source data-testid="og" srcset="https://miro.medium.com/v2/resize:fit:640/0*lVGMidsSsVJQTqpx 640w, https://miro.medium.com/v2/resize:fit:720/0*lVGMidsSsVJQTqpx 720w, https://miro.medium.com/v2/resize:fit:750/0*lVGMidsSsVJQTqpx 750w, https://miro.medium.com/v2/resize:fit:786/0*lVGMidsSsVJQTqpx 786w, https://miro.medium.com/v2/resize:fit:828/0*lVGMidsSsVJQTqpx 828w, https://miro.medium.com/v2/resize:fit:1100/0*lVGMidsSsVJQTqpx 1100w, https://miro.medium.com/v2/resize:fit:1400/0*lVGMidsSsVJQTqpx 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" /></picture></div></div><figcaption class="ns fe nt ne nf nu nv be b bf z dt">Photo by <a class="af nd" href="https://unsplash.com/@mikepetrucci?utm_source=medium&amp;utm_medium=referral" rel="noopener ugc nofollow" target="_blank">Mike Petrucci</a> on <a class="af nd" href="https://unsplash.com/?utm_source=medium&amp;utm_medium=referral" rel="noopener ugc nofollow" target="_blank">Unsplash</a></figcaption></figure><p id="8f19" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj">Let’s start with a PL/SQL function that returns a row of the <a class="af nd" href="https://github.com/oracle-samples/db-sample-schemas/tree/main/human_resources" rel="noopener ugc nofollow" target="_blank">sample schema</a> LOCATIONS table using LOCATIONS%ROWTYPE as the return type. You might create this in Python like:</p><pre class="nh ni nj nk nl nw nx ny bo nz ba bj">import getpass<br />import oracledbun = 'cj'<br />cs = 'localhost/orclpdb1'<br />pw = getpass.getpass(f'Enter password for {un}@{cs}: ')<br />connection = oracledb.connect(user=un, password=pw, dsn=cs)with connection.cursor() as cursor:<br />    cursor.execute("""<br />        create or replace function TestFuncOUT return locations%rowtype as<br />          p locations%rowtype;<br />        begin<br />           select * into p from locations where rownum &lt; 2;<br />           return p;<br />        end;""")<br />    if cursor.warning:<br />        print(cursor.warning)</pre><p id="49e0" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj">The %ROWTYPE attribute defines a record, so you can use python-oracledb’s <code class="cw og oh oi nx b"><a class="af nd" href="https://python-oracledb.readthedocs.io/en/latest/api_manual/connection.html#Connection.gettype" rel="noopener ugc nofollow" target="_blank">gettype()</a></code> object functionality to get the record "shape", and pass this as the expected return type to <code class="cw og oh oi nx b"><a class="af nd" href="https://python-oracledb.readthedocs.io/en/latest/api_manual/cursor.html#Cursor.callfunc" rel="noopener ugc nofollow" target="_blank">callfunc()</a></code> when you invoke TestFuncOUT:</p><pre class="nh ni nj nk nl nw nx ny bo nz ba bj">    rt = connection.gettype("LOCATIONS%ROWTYPE")<br />    r = cursor.callfunc("TESTFUNCOUT", rt)</pre><p id="b557" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj">The python-oracledb type of <code class="cw og oh oi nx b">r</code> is <code class="cw og oh oi nx b">oracledb.DbObject</code>. You can manipulate and view it using that <a class="af nd" href="https://python-oracledb.readthedocs.io/en/latest/api_manual/dbobject_type.html#dbobject-objects" rel="noopener ugc nofollow" target="_blank">class's methods</a>. A handy convenience function that prints an instance is <code class="cw og oh oi nx b">dump_object()</code> defined in <a class="af nd" href="https://github.com/oracle/python-oracledb/blob/v2.2.x/samples/object_dump.py#L86-L105" rel="noopener ugc nofollow" target="_blank">samples/object_dump.py</a>. Calling it on the return value from TestFuncOUT:</p><pre class="nh ni nj nk nl nw nx ny bo nz ba bj">dump_object(r)</pre><p id="44e9" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj">gives:</p><pre class="nh ni nj nk nl nw nx ny bo nz ba bj">{<br />  LOCATION_ID: 1000<br />  STREET_ADDRESS: '1297 Via Cola di Rie'<br />  POSTAL_CODE: '00989'<br />  CITY: 'Roma'<br />  STATE_PROVINCE: None<br />  COUNTRY_ID: 'IT'<br />}</pre><p id="ca94" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj">which is the row returned from the query.</p><p id="b476" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj">If you need to construct a similar object directly in python-oracledb to pass into the database, you can use <code class="cw og oh oi nx b"><a class="af nd" href="https://python-oracledb.readthedocs.io/en/latest/api_manual/dbobject_type.html#DbObjectType.newobject" rel="noopener ugc nofollow" target="_blank">newobject()</a></code> and set any desired fields. For example:</p><pre class="nh ni nj nk nl nw nx ny bo nz ba bj">    rt = connection.gettype("LOCATIONS%ROWTYPE")<br />    r = rt.newobject()<br />    r.CITY = 'Roma'</pre><p id="698c" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj">Passing a value from Python into a PL/SQL block that expects a %ROWTYPE parameter or bind variable is straightforward. Let’s create a PL/SQL procedure that has an IN parameter of type %ROWTYPE:</p><pre class="nh ni nj nk nl nw nx ny bo nz ba bj">cursor.execute("""<br />        create or replace procedure TestProcIN(p in locations%rowtype, city out varchar2) as<br />        begin<br />            city := p.city;<br />        end;""")<br />    if cursor.warning:<br />        print(cursor.warning)</pre><p id="8f34" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj">Now you can call <code class="cw og oh oi nx b">callproc()</code> passing the variable <code class="cw og oh oi nx b">r</code> from the previous <code class="cw og oh oi nx b">callfunc()</code> or <code class="cw og oh oi nx b">newobject()</code> examples in the appropriate parameter position, for example:</p><pre class="nh ni nj nk nl nw nx ny bo nz ba bj">    c = cursor.var(oracledb.DB_TYPE_VARCHAR)<br />    cursor.callproc("TESTPROCIN", [r, c])<br />    print(c.getvalue())</pre><p id="8e7a" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj">This prints:</p><pre class="nh ni nj nk nl nw nx ny bo nz ba bj">Roma</pre><h1 id="b087" class="oj ob gt be ok ol om on oo op oq or os ot ou ov ow ox oy oz pa pb pc pd pe pf bj">Conclusion</h1><p id="a408" class="pw-post-body-paragraph mf mg gt mh b mi pg mk ml mm ph mo mp mq pi ms mt mu pj mw mx my pk na nb nc gm bj">PL/SQL %ROWTYPE attribute values map to python-oracledb’s DbObject instances, allowing easy manipulation and interaction between Python and Oracle Database.</p><h1 id="b379" class="oj ob gt be ok ol om on oo op oq or os ot ou ov ow ox oy oz pa pb pc pd pe pf bj">Installing or Upgrading python-oracledb</h1><p id="93dc" class="pw-post-body-paragraph mf mg gt mh b mi pg mk ml mm ph mo mp mq pi ms mt mu pj mw mx my pk na nb nc gm bj">You can install or upgrade python-oracledb by running:</p><pre class="nh ni nj nk nl nw nx ny bo nz ba bj">python -m pip install oracledb --upgrade</pre><p id="624d" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj">The <code class="cw og oh oi nx b">pip</code> options <code class="cw og oh oi nx b">--proxy</code> and <code class="cw og oh oi nx b">--user</code> may be useful in some environments. See <a class="af nd" href="https://python-oracledb.readthedocs.io/en/latest/user_guide/installation.html" rel="noopener ugc nofollow" target="_blank">python-oracledb Installation</a> for details.</p><h1 id="63af" class="oj ob gt be ok ol om on oo op oq or os ot ou ov ow ox oy oz pa pb pc pd pe pf bj">Python-oracledb References</h1><p id="9b52" class="pw-post-body-paragraph mf mg gt mh b mi pg mk ml mm ph mo mp mq pi ms mt mu pj mw mx my pk na nb nc gm bj">Home page: <a class="af nd" href="https://oracle.github.io/python-oracledb/index.html" rel="noopener ugc nofollow" target="_blank">oracle.github.io/python-oracledb/index.html</a></p><p id="fe1c" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj">Installation instructions: <a class="af nd" href="https://python-oracledb.readthedocs.io/en/latest/user_guide/installation.html" rel="noopener ugc nofollow" target="_blank">python-oracledb.readthedocs.io/en/latest/installation.html</a></p><p id="4644" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj">Documentation: <a class="af nd" href="https://python-oracledb.readthedocs.io/en/latest/index.html" rel="noopener ugc nofollow" target="_blank">python-oracledb.readthedocs.io/en/latest/index.html</a></p><p id="7039" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj">Release Notes: <a class="af nd" href="https://python-oracledb.readthedocs.io/en/latest/release_notes.html" rel="noopener ugc nofollow" target="_blank">python-oracledb.readthedocs.io/en/latest/release_notes.html</a></p><p id="fd62" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj">Discussions: <a class="af nd" href="https://github.com/oracle/python-oracledb/discussions" rel="noopener ugc nofollow" target="_blank">github.com/oracle/python-oracledb/discussions</a></p><p id="be37" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj">Issues: <a class="af nd" href="https://github.com/oracle/python-oracledb/issues" rel="noopener ugc nofollow" target="_blank">github.com/oracle/python-oracledb/issues</a></p><p id="a8f2" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj">Source Code Repository: <a class="af nd" href="https://github.com/oracle/python-oracledb" rel="noopener ugc nofollow" target="_blank">github.com/oracle/python-oracledb</a></p></div>]]></description>
      <link>https://medium.com/oracledevs/using-the-rowtype-attribute-with-python-oracledb-5f10c44bfb02?source=rss-adc937c3a9d------2</link>
      <guid>https://medium.com/oracledevs/using-the-rowtype-attribute-with-python-oracledb-5f10c44bfb02?source=rss-adc937c3a9d------2</guid>
      <pubDate>Sat, 06 Jul 2024 07:33:00 +0200</pubDate>
    </item>
    <item>
      <title><![CDATA[PHP 8.4.0 Alpha 1 available for testing - PHP: Hypertext Preprocessor]]></title>
      <description><![CDATA[<div><header class="title"><time datetime="2024-07-05T13:22:12+00:00">05 Jul 2024</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the first testing release of PHP 8.4.0, Alpha 1. This starts the PHP 8.4 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php84">PHP Wiki</a>.</p><p>For source downloads of PHP 8.4.0 Alpha 1 please visit the <a href="https://downloads.php.net/~saki/">download page</a>.</p><p>Please carefully test this version and report any issues found using <a href="https://github.com/php/php-src/issues">the bug tracking system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.4.0alpha1/NEWS">NEWS</a> file, or the <a href="https://github.com/php/php-src/blob/php-8.4.0alpha1/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be Alpha 2, planned for 18 Jul 2024.</p><p>The signatures for the release can be found in the <a href="https://gist.github.com/SakiTakamachi/d3e32b780590319bee72d8402593a3ca">manifest</a> or on the <a href="https://qa.php.net/">QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></div><div><header class="title"><time datetime="2024-07-04T22:59:58+00:00">04 Jul 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.3.9. This is a bug fix release.</p><p>All PHP 8.3 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.3.9 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.3.9">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-07-04T14:43:24+00:00">04 Jul 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.21. This is a bug fix release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.21 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.21">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-06-06T14:56:47+00:00">06 Jun 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.20. This is a security release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.20 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.20">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-06-06T14:42:14+00:00">06 Jun 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.3.8. This is a security release.</p><p>All PHP 8.3 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.3.8 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.3.8">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-06-06T14:12:51+00:00">06 Jun 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.1.29. This is a security release.</p><p>All PHP 8.1 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.1.29 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.1.29">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-05-09T14:40:06+00:00">09 May 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.3.7. This is a bug fix release.</p><p>All PHP 8.3 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.3.7 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.3.7">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-05-09T13:48:33+00:00">09 May 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.19. This is a bug fix release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.19 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.19">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-04-24T18:40:29+00:00">24 Apr 2024</time>
</header><div class="newscontent"><p>EDIT 2024-04-25: Clarified when a PHP application is vulnerable to this bug.</p><p>Recently, a bug in <strong>glibc</strong> version 2.39 and older (<a href="https://nvd.nist.gov/vuln/detail/CVE-2024-2961">CVE-2024-2961</a>) was uncovered where a buffer overflow in character set conversions <strong>to</strong> the ISO-2022-CN-EXT character set can result in remote code execution.</p><p>This specific buffer overflow in glibc is exploitable through PHP, which exposes the iconv functionality of glibc to do character set conversions via the <a href="https://www.php.net/manual/en/function.iconv.php">iconv extension</a>. Although the bug is exploitable in the context of the PHP Engine, the bug is not in PHP. It is also not directly exploitable remotely.</p><p>The bug is exploitable, <strong>if and only if</strong>, the PHP application calls iconv <a href="https://www.php.net/manual/en/ref.iconv.php">functions</a> or <a href="https://www.php.net/manual/en/filters.convert.php#filters.convert.iconv">filters</a> with user-supplied character sets.</p><p>Applications are <strong>not</strong> vulnerable if:</p><ul><li>Glibc security updates from the distribution have been installed.</li>
<li>Or the iconv extension is not loaded.</li>
<li>Or the vulnerable character set has been removed from gconv-modules-extra.conf.</li>
<li>Or the application passes only specifically allowed character sets to iconv.</li>
</ul><p>Moreover, when using a user-supplied character set, it is good practice for applications to accept only specific charsets that have been explicitly allowed by the application. One example of how this can be done is by using an allow-list and the <a href="https://www.php.net/manual/en/function.array-search"><code>array_search()</code></a> function to check the encoding before passing it to iconv. For example: <code>array_search($charset, $allowed_list, true)</code></p><p>There are numerous reports online with titles like "Mitigating the iconv Vulnerability for PHP (CVE-2024-2961)" or "PHP Under Attack". These titles are misleading as this is <strong>not</strong> a bug in PHP itself.</p><p>If your PHP application is vulnerable, we first recommend to check if your Linux distribution has already published patched variants of glibc. <a href="https://security-tracker.debian.org/tracker/CVE-2024-2961">Debian</a>, CentOS, and others, have already done so, and please upgrade as soon as possible.</p><p>Once an update is available in glibc, updating that package on your Linux machine will be enough to alleviate the issue. You do not need to update PHP, as glibc is a dynamically linked library.</p><p>If your Linux distribution has not published a patched version of glibc, there is no fix for this issue. However, there exists a workaround described in <a href="https://rockylinux.org/news/glibc-vulnerability-april-2024/">GLIBC Vulnerability on Servers Serving PHP</a> which explains a way on how to remove the problematic character set from glibc. Perform this procedure for every gconv-modules-extra.conf file that is available on your system.</p><p>PHP users on Windows are not affected.</p><p>Therefore, a new version of PHP will not be released for this vulnerability.</p></div></div><div><header class="title"><time datetime="2024-04-12T15:42:40+00:00">12 Apr 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.1.28. This is a security release.</p><p>All PHP 8.1 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.1.28 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.1.28">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-04-11T14:34:04+00:00">11 Apr 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.3.6. This is a security release.</p><p>All PHP 8.3 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.3.6 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.3.6">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-04-11T13:37:51+00:00">11 Apr 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.18. This is a security release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.18 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.18">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-03-14T21:02:45+00:00">14 Mar 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.3.4. This is a bug fix release.</p><p>All PHP 8.3 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.3.4 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.3.4">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-03-14T15:21:29+00:00">14 Mar 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.17. This is a bug fix release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.17 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.17">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-02-15T13:36:20-05:00">15 Feb 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.16. This is a bug fix release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.16 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.16">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-02-15T15:48:46+00:00">15 Feb 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.3.3. This is a bug fix release.</p><p>All PHP 8.3 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.3.3 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.3.3">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-01-18T15:35:45+00:00">18 Jan 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.15. This is a bug fix release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.15 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.15">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-01-18T14:47:41+00:00">18 Jan 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.3.2. This is a bug fix release.</p><p>All PHP 8.3 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.3.2 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.3.2">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2023-12-21T14:28:29-05:00">21 Dec 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.14. This is a bug fix release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.14 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.14">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2023-12-21T16:12:41+00:00">21 Dec 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.1.27. This is a bug fix release.</p><p>All PHP 8.1 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.1.27 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.1.27">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2023-12-21T07:48:56-08:00">21 Dec 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.3.1. This is a bug fix release.</p><p>All PHP 8.3 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.3.1 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.3.1">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2023-11-23T18:24:51+00:00">23 Nov 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.1.26. This is a bug fix release.</p><p>All PHP 8.1 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.1.26 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.1.26">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2023-11-23T15:43:03+00:00">23 Nov 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.3.0. This release marks the latest minor release of the PHP language.</p><p>PHP 8.3 comes with numerous improvements and new features such as:</p><p>For source downloads of PHP 8.3.0 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.3.0">ChangeLog</a>.</p><p>The <a href="https://php.net/manual/en/migration83.php">migration guide</a> is available in the PHP Manual. Please consult it for the detailed list of new features and backward incompatible changes.</p><p>Kudos to all the contributors and supporters!</p></div></div><div><header class="title"><time datetime="2023-11-23T12:24:42+00:00">23 Nov 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.13. This is a bug fix release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.13 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.13">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2023-11-09T09:33:47-08:00">09 Nov 2023</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the release of PHP 8.3.0, RC 6. This is the sixth and final release candidate, continuing the PHP 8.3 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php83">PHP Wiki</a>.</p><p>For source downloads of PHP 8.3.0, RC 6 please visit the <a href="https://downloads.php.net/~eric">download page</a>.</p><p>Please carefully test this version and report any issues found in the <a href="http://bugs.php.net">bug reporting system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.3.0RC6/NEWS">NEWS</a> file or the <a href="https://github.com/php/php-src/blob/php-8.3.0RC6/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be the production-ready, general availability release, planned for 23 November 2023.</p><p>The signatures for the release can be found in <a href="https://gist.github.com/ericmann/ceaadbc09bdbb49efb74212a6c8cf02a">the manifest</a> or on <a href="https://qa.php.net/">the QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></div>]]></description>
      <link>https://www.php.net/index.php#2024-07-05-1</link>
      <guid>https://www.php.net/index.php#2024-07-05-1</guid>
      <pubDate>Fri, 05 Jul 2024 02:00:00 +0200</pubDate>
    </item>
    <item>
      <title><![CDATA[Creating a fake download counter with Web Components - Evert Pot]]></title>
      <description><![CDATA[<p>Over the years I’ve written several open source libraries. They’re mostly unglamorous and utilitarian, but a bunch of them obtained got a decent download count, so I thought it would be fun to try and get a grand total and show a ‘live’ download counter on my blog.</p><p>This is how that looks like:</p><blockquote>
<p>My open source packages were downloaded roughly <strong>138945563</strong> times.</p>
</blockquote><p>Like most live counters, this number isn’t tracked in real-time. Instead it just uses a start number and updates the number based on an average number of downloads.</p><p>One day it might be nice to make it live, but this is a static blog and this would need proper hosting and a database.</p><h3 id="why-is-this-number-so-high">Why is this number so high?</h3><p>This data comes from NPM and Packagist, and they both count any download. So this number doesn’t represent necessarily 138 million users, but simply this many downloads by any means including bots, CI environments and so on. I think for both package managers the goal was probably not to have a realistic representation of users, but rather a number that makes developers feel good. And I like that. It’s nice to see a number go up and it’s still a nice proxy for relative popularity.</p><h2 id="the-web-component">The Web Component</h2><p>This seemed like a good use-case for a web component. Always wanted to build one! I was surprised how easy it was.</p><p>This is how this looks in the HTML:</p><div class="language-html highlighter-rouge highlight"><pre>&lt;p&gt;
  My open source packages were downloaded roughly
  &lt;strong&gt;
    &lt;download-counter inc-per-day="157444" date="2024-06-29T15:34:00Z" &gt;
      138945563
    &lt;/download-counter&gt;
  &lt;/strong&gt; times.
&lt;/p&gt;
</pre></div><p>What’s nice is that if Javascript is not enabled, or Web Components are not supported, this will just fall back on showing the static number.</p><p>I included 3 parameters:</p><ul><li>The last recorded download count (in the element value)</li>
<li>When that number was recorded (date)</li>
<li>Average number of downloads per day.</li>
</ul><p>I wanted to include the date because I only intend to update these numbers rarely, so we need to know how many downloads have elapsed since the last time.</p><p>Writing the web component was surprisingly straightforward too. Here is it in its fully glory:</p><div class="language-javascript highlighter-rouge highlight"><pre>class DownloadCounter extends HTMLElement {
  connectedCallback() {
    this.count = +this.textContent;
    this.date = new Date(this.getAttribute('date'));
    this.inc = (+this.getAttribute('inc-per-day')) / (3600 * 24 * 1000)
    this.calculateCurrentDownloads();
  }
  calculateCurrentDownloads() {
    const currentDownloads =
      Math.floor(
      this.count +
      (Date.now()-this.date) * this.inc
      );
    // Intl.NumberFormat adds thousands separators
    this.textContent = Intl.NumberFormat().format(currentDownloads);
    setTimeout(
      () =&gt; this.calculateCurrentDownloads(),
      // Add some randomnes
      Math.floor(Math.random() * 150)+50,
    );
  }
}
customElements.define(
  'download-counter',
  DownloadCounter,
);
</pre></div><p>Now just include the file in the HTML and you’re good to go:</p><div class="language-javascript highlighter-rouge highlight"><pre>&lt;script type="module" src="/assets/js/downloadcounter.mjs"&gt;&lt;/script&gt;
</pre></div><h2 id="obtaining-the-data">Obtaining the data</h2><p>I’ve published 20 PHP libraries on <a href="https://packagist.org/">packagist</a> and 30 Javascript libraries on <a href="https://www.npmjs.com/">NPM</a>. This is too much to count, so instead I wrote some scripts that pull in the data for their respective APIs.</p><p>You cannot easily ask these APIs what the download count or download rate at a given date was, and for both the numbers might be a bit delayed. So I’ve opted to simply:</p><ul><li>Get a grand total of all downloads up until this date.</li>
<li>Wait at least 24 hours or more.</li>
<li>Get another grand total and use the difference to caclulate average download rate.</li>
</ul><p>Below is my approach for getting the numbers from NPM and Packagist. It’s a bit messy and imperative.</p><h3 id="npm">NPM</h3><p>The NPM api gave me weird, incomplete results for getting the whole list of packages I’ve authored, so I worked around this by hardcoding some package names, and then augmenting this with the result of 3 searches.</p><p>This gives us the full list of packages I’m interested in:</p><div class="language-javascript highlighter-rouge highlight"><pre>// Searches
const npmSearches = [
  // by author
  'author:evrt',
  // by org name
  'scope:badgateway',
  'scope:curveball',
];
// Hardcoded extra packages that for some reason didn't get returned with
// the searches
const npmPackages = {
  'davclient.js': 0,
  'structured-headers': 0,
  'bigint-money': 0,
  'fetch-mw-oauth2': 0,
  'hal-types': 0,
  'react-ketting': 0,
  'ketting': 0,
  'html-form-enhancer': 0,
  'changelog-tool': 0,
};
async function fetchNpmPackageList() {
  for(const search of npmSearches) {
    const res = await fetch('https://registry.npmjs.org/-/v1/search?text=' + search);
    const body = await res.json();
    for(const object of body.objects) {
      npmPackages[object.package.name] = 0;
    }
  }
}
</pre></div><p>NPM doesn’t return absolute total download counts but instead we can get a count for a specific time range with a maximum range of 18 months. I’ve opted to instead to get download counts per year, counting backwards for each package until get a result of 0.</p><div class="language-javascript highlighter-rouge highlight"><pre>async function fetchNpmDownloadCounts(packageName) {
  let year = new Date().getFullYear();
  let count = 0;
  let yearCount;
  do {
    yearCount = await fetchNpmDownloadCountsByYear(packageName, year);
    count += yearCount;
    year--;
  } while (yearCount &gt; 0);
  console.log('%s: %i', packageName, count);
  return count;
}
async function fetchNpmDownloadCountsByYear(packageName, year) {
  const res = await fetch(`https://api.npmjs.org/downloads/point/${year}-01-01:${year}-12-31/${packageName}`);
  const body = await res.json();
  return body.downloads;
}
</pre></div><h3 id="packagist">Packagist</h3><p>Getting totals from packagist was considerably easier:</p><div class="language-javascript highlighter-rouge highlight"><pre>const packagistOrgs = [
  'sabre',
  'evert',
];
const packagistPackages = {};
async function fetchPackagistPackages() {
  for(const vendor of packagistOrgs) {
    const res = await fetch(`https://packagist.org/packages/list.json?vendor=${vendor}`);
    const body = await res.json();
    for(const pkg of body.packageNames) {
      packagistPackages[pkg] = 0;
    }
  }
}
async function fetchPackagistDownloadCounts(packageName) {
  const res = await fetch(`https://packagist.org/packages/${packageName}/stats.json`);
  const json = await res.json();
  const count = json.downloads.total;
  console.log('%s: %i', packageName, count);
  return count;
}
</pre></div><h3 id="putting-it-together">Putting it together</h3><div class="language-javascript highlighter-rouge highlight"><pre>async function main() {
  await fetchNpmPackageList();
  await fetchPackagistPackages();
  for(const pkg of Object.keys(npmPackages)) {
    npmPackages[pkg] = await fetchNpmDownloadCounts(pkg);
  }
  for(const pkg of Object.keys(packagistPackages)) {
    packagistPackages[pkg] = await fetchPackagistDownloadCounts(pkg);
  }
  const packagesCombined = [];
  for(const [packageName, downloads] of Object.entries(npmPackages)) {
    packagesCombined.push({
      ecosystem: 'npm',
      packageName,
      downloads
    });
  }
  for(const [packageName, downloads] of Object.entries(packagistPackages)) {
    packagesCombined.push({
      ecosystem: 'packagist',
      packageName,
      downloads
    });
  }
  console.log(packagesCombined);
  console.log('Total: %i', packagesCombined.reduce((acc, cur) =&gt; acc+cur.downloads, 0));
}
await main();
</pre></div><h2 id="conclusion">Conclusion</h2><p>Whenever I need small bits of Javascript to enhance a web application (and not a full-blown framework) I tend to write code that looks for an element with a particular class, and then start my logic and hook up events.</p><p>Web Components seems like a really great replacement for that.</p><p>Got comments? Liked this aticle? You can reply to <a href="https://indieweb.social/@evert/112717778570631838">this Mastodon post</a> to make the comments show up here.</p>]]></description>
      <link>https://evertpot.com/webcomponent-download-counter/</link>
      <guid>https://evertpot.com/webcomponent-download-counter/</guid>
      <pubDate>Tue, 02 Jul 2024 18:07:00 +0200</pubDate>
    </item>
    <item>
      <title><![CDATA[Oracle Application Continuity — for continuous availability - Christopher Jones]]></title>
      <description><![CDATA[<div><div></div><p id="b651" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj">Applications need to be resilient to infrastructure glitches. Oracle Database has powerful features that help your users get their jobs done, without them being aware of planned or unplanned database downtime.</p><figure class="ng nh ni nj nk nl nd ne paragraph-image"><div role="button" tabindex="0" class="nm nn fi no bg np"><div class="nd ne nf"><picture><source srcset="https://miro.medium.com/v2/resize:fit:640/format:webp/0*GpMU2dSPDRcPYDL6 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/0*GpMU2dSPDRcPYDL6 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/0*GpMU2dSPDRcPYDL6 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/0*GpMU2dSPDRcPYDL6 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/0*GpMU2dSPDRcPYDL6 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/0*GpMU2dSPDRcPYDL6 1100w, https://miro.medium.com/v2/resize:fit:1400/format:webp/0*GpMU2dSPDRcPYDL6 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" type="image/webp" /><source data-testid="og" srcset="https://miro.medium.com/v2/resize:fit:640/0*GpMU2dSPDRcPYDL6 640w, https://miro.medium.com/v2/resize:fit:720/0*GpMU2dSPDRcPYDL6 720w, https://miro.medium.com/v2/resize:fit:750/0*GpMU2dSPDRcPYDL6 750w, https://miro.medium.com/v2/resize:fit:786/0*GpMU2dSPDRcPYDL6 786w, https://miro.medium.com/v2/resize:fit:828/0*GpMU2dSPDRcPYDL6 828w, https://miro.medium.com/v2/resize:fit:1100/0*GpMU2dSPDRcPYDL6 1100w, https://miro.medium.com/v2/resize:fit:1400/0*GpMU2dSPDRcPYDL6 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" /></picture></div></div><figcaption class="nr fe ns nd ne nt nu be b bf z dt">Enjoying some “downtime”. Photo by <a class="af nv" href="https://unsplash.com/@veloradio?utm_source=medium&amp;utm_medium=referral" rel="noopener ugc nofollow" target="_blank">Rapha Wilde</a> on <a class="af nv" href="https://unsplash.com/?utm_source=medium&amp;utm_medium=referral" rel="noopener ugc nofollow" target="_blank">Unsplash</a></figcaption></figure><p id="9205" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj">My colleagues <a class="nw in fd" href="https://medium.com/u/a74d404166c0" rel="noopener" target="_blank">Veronica Dumitriu</a> and <a class="nw in fd" href="https://medium.com/u/574e21edecf8" rel="noopener" target="_blank">Nancy Ikeda</a> previously posted a blog <a class="af nv" href="https://medium.com/oracledevs/how-to-make-application-continuity-most-effective-in-oracle-database-23c-53b52ea37e68" rel="noopener">How to Make Application Continuity Most Effective in Oracle Database 23c</a> covering AC (“Application Continuity”) and the related TAC (“Transparent Application Continuity”) features. These High Availability technologies are part of Oracle Database and Oracle Client. They allow applications to continue uninterrupted if there is an outage accessing one database node. They function by the driver client libraries recording the “work” that an application does. If the database instance becomes unavailable before all that “work” is committed to the database, the driver transparently connects to another database instance and replays all the recorded work, before letting the app continue as if there had been no outage. AC and TAC need a database that is configured with multiple instances, e.g RAC.</p><p id="3c18" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj">Veronica and Nancy’s post uses examples from the C language Oracle Call Interface API, which is one of the primary APIs for data access. Here I want to share some working notes about AC and TAC with <a class="af nv" href="https://oracle.github.io/python-oracledb/" rel="noopener ugc nofollow" target="_blank">python-oracledb</a>, the Oracle Database driver for Python.</p><p id="5b92" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj">Before my sabbatical at the start of the year, I had been looking at python-oracledb with AC and TAC, in particular how to run the <a class="af nv" href="https://docs.oracle.com/en/database/oracle/oracle-database/23/racad/ensuring-application-continuity.html#GUID-9D9A06C8-CEAC-4564-8D00-4A300D009EA4" rel="noopener ugc nofollow" target="_blank">‘</a><code class="cw nx ny nz oa b"><a class="af nv" href="https://docs.oracle.com/en/database/oracle/oracle-database/23/racad/ensuring-application-continuity.html#GUID-9D9A06C8-CEAC-4564-8D00-4A300D009EA4" rel="noopener ugc nofollow" target="_blank">acchk</a></code><a class="af nv" href="https://docs.oracle.com/en/database/oracle/oracle-database/23/racad/ensuring-application-continuity.html#GUID-9D9A06C8-CEAC-4564-8D00-4A300D009EA4" rel="noopener ugc nofollow" target="_blank">’ tool</a> to check application coverage. AC and TAC are implemented in Oracle Client libraries, and so are transparently available to python-oracledb apps when using <a class="af nv" href="https://python-oracledb.readthedocs.io/en/latest/user_guide/initialization.html#enabling-python-oracledb-thick-mode" rel="noopener ugc nofollow" target="_blank">Thick mode</a> against Oracle Datase (on-premise or in the Cloud). AC and TAC are similarly available to other drivers like <a class="af nv" href="https://www.npmjs.com/package/oracledb" rel="noopener ugc nofollow" target="_blank">node-oracledb</a> in Thick mode.</p><p id="5ff1" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj">AC and TAC are primarily used for unplanned database outages. Applications that use an Oracle connection pool will handle planned downtime gracefully.</p><p id="a76b" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj">My working notes show how to enable AC and TAC on Oracle Autonomous Database and see what protection they give a sample application. As good as AC and TAC are, there are <a class="af nv" href="https://docs.oracle.com/en/database/oracle/oracle-database/23/racad/ensuring-application-continuity.html#GUID-2400FAAD-0BB2-48AF-B1F6-358EBA724028" rel="noopener ugc nofollow" target="_blank">some things</a> they can’t (and shouldn’t) recover.</p><p id="8e93" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj">You can use <code class="cw nx ny nz oa b">acchk</code> to review which code paths in your app will be protected and what database work will be replayed by AC or TAC in the event the database instance currently in use has a failure.</p><p id="c8d5" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj"><strong class="mh gu">A few general app suggestions</strong>:</p><ul class=""><li id="d8a5" class="mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc ob oc od bj">Use python-oracledb <a class="af nv" href="https://python-oracledb.readthedocs.io/en/latest/user_guide/initialization.html#enabling-python-oracledb-thick-mode" rel="noopener ugc nofollow" target="_blank">Thick mode</a>. This mode is a must.</li><li id="7731" class="mf mg gt mh b mi oe mk ml mm of mo mp mq og ms mt mu oh mw mx my oi na nb nc ob oc od bj">Use a <a class="af nv" href="https://python-oracledb.readthedocs.io/en/latest/user_guide/connection_handling.html#connection-pooling" rel="noopener ugc nofollow" target="_blank">connection pool</a>. Python-oracledb doesn’t (yet) expose the <code class="cw nx ny nz oa b">OCIRequestBegin()</code> and <code class="cw nx ny nz oa b">OCIRequestEnd()</code> functionality.</li><li id="4927" class="mf mg gt mh b mi oe mk ml mm of mo mp mq og ms mt mu oh mw mx my oi na nb nc ob oc od bj">Use <code class="cw nx ny nz oa b">ORDER BY</code> or <code class="cw nx ny nz oa b">GROUP BY</code> in SQL statements</li><li id="e908" class="mf mg gt mh b mi oe mk ml mm of mo mp mq og ms mt mu oh mw mx my oi na nb nc ob oc od bj">Set <code class="cw nx ny nz oa b">Connection.module</code> and <code class="cw nx ny nz oa b">Connection.action</code></li><li id="4d50" class="mf mg gt mh b mi oe mk ml mm of mo mp mq og ms mt mu oh mw mx my oi na nb nc ob oc od bj">Use the Oracle Database 19.11+ <code class="cw nx ny nz oa b">acchck</code> coverage report tool<br /> — This is the successor to Ora*CHK<br /> — Use it by enabling AC or TAC and then:<br /> — Use PL/SQL <code class="cw nx ny nz oa b">DBMS_APP_CONT_ADMIN</code> package to enable recording<br /> — Run your app<br /> — Use <code class="cw nx ny nz oa b">DBMS_APP_CONT_ADMIN</code> to get a coverage report</li></ul><h1 id="f664" class="oj ok gt be ol om on oo op oq or os ot ou ov ow ox oy oz pa pb pc pd pe pf pg bj">Testing acchk</h1><p id="c9e2" class="pw-post-body-paragraph mf mg gt mh b mi ph mk ml mm pi mo mp mq pj ms mt mu pk mw mx my pl na nb nc gm bj">I was testing using Oracle Autonomous Database. To enable <code class="cw nx ny nz oa b">acchk</code> in an on-premise database, review your Oracle documentation.</p><p id="7610" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj">Enable AC:</p><pre class="ng nh ni nj nk pm oa pn bo po ba bj">sqlplus -l admin@'tcps://adb.xxxx.oraclecloud.com:1522/xxxxx_cjdb_tpurgent.adb.oraclecloud.com?wallet_location=/opt/oracle/cjdb'execute dbms_app_cont_admin.enable_ac('xxxxx_CJDB_tpurgent.adb.oraclecloud.com', 'LEVEL1', 600);select name, failover_type from dba_services;</pre><p id="878c" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj">Or enable TAC:</p><pre class="ng nh ni nj nk pm oa pn bo po ba bj">execute DBMS_APP_CONT_ADMIN.ENABLE_TAC('xxxxx_cjdb_tpurgent.adb.oraclecloud.com', 'AUTO', 600);</pre><p id="c920" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj">Give myself access:</p><pre class="ng nh ni nj nk pm oa pn bo po ba bj">grant acchk_read to cj;grant execute on dbms_app_cont_admin to cj;</pre><p id="af4c" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj">Enable recording:</p><pre class="ng nh ni nj nk pm oa pn bo po ba bj">sqlplus -l cj@'tcps://adb.xxxx.oraclecloud.com:1522/xxxxx_cjdb_tpurgent.adb.oraclecloud.com?wallet_location=/opt/oracle/cjdb'execute dbms_app_cont_admin.acchk_set(true);</pre><p id="ab98" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj">The run your Python application eg.:</p><pre class="ng nh ni nj nk pm oa pn bo po ba bj">python acchk-test.py</pre><p id="9be6" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj">My app is a web service so put some load on it:</p><pre class="ng nh ni nj nk pm oa pn bo po ba bj">ab -n 100 -c 4 http://127.0.0.1:7000/</pre><p id="2276" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj">View the <code class="cw nx ny nz oa b">acchk</code> report:</p><pre class="ng nh ni nj nk pm oa pn bo po ba bj">set serveroutput on format wrapped linesize 160<br />execute dbms_app_cont_report.acchk_report(dbms_app_cont_report.FULL)</pre><p id="bc85" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj">Or a summary report:</p><pre class="ng nh ni nj nk pm oa pn bo po ba bj">set serveroutput on format wrapped linesize 160<br />execute dbms_app_cont_report.acchk_report(dbms_app_cont_report.SUMMARY)</pre><p id="e5a2" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj">And disable the analysis:</p><pre class="ng nh ni nj nk pm oa pn bo po ba bj">execute dbms_app_cont_admin.acchk_set(false);</pre><p id="f8dd" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj">And clear records:</p><pre class="ng nh ni nj nk pm oa pn bo po ba bj">execute dbms_app_cont_admin.acchk_purge(purge_all=&gt;true);</pre><h1 id="c555" class="oj ok gt be ol om on oo op oq or os ot ou ov ow ox oy oz pa pb pc pd pe pf pg bj">References</h1><ul class=""><li id="72be" class="mf mg gt mh b mi ph mk ml mm pi mo mp mq pj ms mt mu pk mw mx my pl na nb nc ob oc od bj"><a class="af nv" href="https://docs.oracle.com/en/database/oracle/oracle-database/23/racad/ensuring-application-continuity.html#GUID-9D9A06C8-CEAC-4564-8D00-4A300D009EA4" rel="noopener ugc nofollow" target="_blank">Application Continuity Protection Check (acchk)</a></li></ul></div>]]></description>
      <link>https://cjones-oracle.medium.com/oracle-application-continuity-for-continuous-availability-633aa570f374?source=rss-adc937c3a9d------2</link>
      <guid>https://cjones-oracle.medium.com/oracle-application-continuity-for-continuous-availability-633aa570f374?source=rss-adc937c3a9d------2</guid>
      <pubDate>Thu, 27 Jun 2024 08:35:00 +0200</pubDate>
    </item>
    <item>
      <title><![CDATA[Technical Briefs on VECTOR with python-oracledb and node-oracledb - Christopher Jones]]></title>
      <description><![CDATA[<div><div></div><p id="0730" class="pw-post-body-paragraph md me gt mf b mg mh mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na gm bj">For those that like ‘official’ things, technical briefs <a class="af nb" href="https://download.oracle.com/ocomdocs/global/python-oracledb_Vector_Technical_Brief_Oracle_Database_23ai.pdf" rel="noopener ugc nofollow" target="_blank">Using Oracle Database 23ai Vectors in python-oracledb</a> and <a class="af nb" href="https://download.oracle.com/ocomdocs/global/node-oracledb_Vector_Technical_Brief_Oracle_Database_23ai.pdf" rel="noopener ugc nofollow" target="_blank">Using Oracle Database vectors in node-oracledb</a> discuss using the Oracle Database 23ai VECTOR data type with the respective database drivers.</p><figure class="nf ng nh ni nj nk nc nd paragraph-image"><div role="button" tabindex="0" class="nl nm fi nn bg no"><div class="nc nd ne"><picture><source srcset="https://miro.medium.com/v2/resize:fit:640/format:webp/0*A7-mhKPSodVXr2Ya 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/0*A7-mhKPSodVXr2Ya 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/0*A7-mhKPSodVXr2Ya 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/0*A7-mhKPSodVXr2Ya 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/0*A7-mhKPSodVXr2Ya 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/0*A7-mhKPSodVXr2Ya 1100w, https://miro.medium.com/v2/resize:fit:1400/format:webp/0*A7-mhKPSodVXr2Ya 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" type="image/webp" /><source data-testid="og" srcset="https://miro.medium.com/v2/resize:fit:640/0*A7-mhKPSodVXr2Ya 640w, https://miro.medium.com/v2/resize:fit:720/0*A7-mhKPSodVXr2Ya 720w, https://miro.medium.com/v2/resize:fit:750/0*A7-mhKPSodVXr2Ya 750w, https://miro.medium.com/v2/resize:fit:786/0*A7-mhKPSodVXr2Ya 786w, https://miro.medium.com/v2/resize:fit:828/0*A7-mhKPSodVXr2Ya 828w, https://miro.medium.com/v2/resize:fit:1100/0*A7-mhKPSodVXr2Ya 1100w, https://miro.medium.com/v2/resize:fit:1400/0*A7-mhKPSodVXr2Ya 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" /></picture></div></div><figcaption class="nq fe nr nc nd ns nt be b bf z dt">Photo by <a class="af nb" href="https://unsplash.com/@telun_photo?utm_source=medium&amp;utm_medium=referral" rel="noopener ugc nofollow" target="_blank">TE LUN OU YANG</a> on <a class="af nb" href="https://unsplash.com/?utm_source=medium&amp;utm_medium=referral" rel="noopener ugc nofollow" target="_blank">Unsplash</a></figcaption></figure></div>]]></description>
      <link>https://cjones-oracle.medium.com/technical-briefs-on-vector-with-python-oracledb-and-node-oracledb-3ecade5b662d?source=rss-adc937c3a9d------2</link>
      <guid>https://cjones-oracle.medium.com/technical-briefs-on-vector-with-python-oracledb-and-node-oracledb-3ecade5b662d?source=rss-adc937c3a9d------2</guid>
      <pubDate>Fri, 21 Jun 2024 23:42:00 +0200</pubDate>
    </item>
    <item>
      <title><![CDATA[Using Monolog's TestHandler - Rob Allen]]></title>
      <description><![CDATA[<p>When I write integration tests with <a href="https://phpunit.de/">PHPUnit</a>, I find it helpful use <a href="https://github.com/Seldaek/monolog">Monolog</a>‘s TestHandler to check that the logs I expect are generated.</p><p>It’s reasonably common that classes that write to a log take a <code>PSR\Log\LoggerInterface</code> in their constructor and then use that for logging. This usually logs to the error handler for pushing to Sentry or whatnot. This makes testing easy!</p><p>For testing we can use the <code>TestHandler</code> which stores the logs it receives and then they can then be inspected.</p><p>We set up like this:</p><pre lang="php">
&lt;?php
namespace Test\Integration;
use Monolog\Handler\TestHandler;
use Monolog\Logger;
use PHPUnit\Framework\TestCase;
class FooTest extends TestCase
{
    protected TestHandler $testHandler;
    protected Logger $logger;
    public function setUp(): void
    {
        $this-&gt;testHandler = new TestHandler();
        $this-&gt;logger = new Logger('test', [$handler]);
    }
    // tests here
}
</pre><p>Then we can use it in a test like this:</p><pre lang="pre">
public function testFoo(): void
{
    $foo = new Foo($this-&gt;logger);
    $result = $foo-&gt;bar();
    $this-&gt;assertTrue($result);
    $this-&gt;assertTrue($this-&gt;testHandler-&gt;hasInfoThatContains('Created Baz'));
}
</pre><p><code>TestHandler</code> has a number of methods that allow you to determine if a specific log has been written, along with <code>getRecords()</code>, <code>clear()</code>, etc to allow full inspection and control of the test log. Peruse the <a href="https://github.com/Seldaek/monolog/blob/main/src/Monolog/Handler/TestHandler.php">source for the class</a> to see all the options, noting particularly the set of convenience methods in the DocBlock.</p><p>If your system under test uses a PSR-3 logger, then Monolog’s <code>TestHandler</code> is a lovely way to test that your logs are as expected.</p>]]></description>
      <link>https://akrabat.com/using-monologs-testhandler/</link>
      <guid>https://akrabat.com/using-monologs-testhandler/</guid>
      <pubDate>Tue, 18 Jun 2024 12:00:00 +0200</pubDate>
    </item>
    <item>
      <title><![CDATA[Implicit Connection Pooling when connections overload your database - Christopher Jones]]></title>
      <description><![CDATA[<div><div></div><p id="51de" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj">When a long-running application keeps a database connection open for the app lifetime, it is likely that the connection is often idle and not being used to execute SQL statements. However this holds the connection’s server process and session memory open on the database host, ultimately limiting the number of other users who can connect. When re-architecting to use an Oracle driver connection pool isn’t possible, a simple connection string change can make use of Oracle Database 23ai “Implicit Connection Pooling” to share the database host resources. This reduces the memory required, and allows the database to be more scalable.</p><figure class="ng nh ni nj nk nl nd ne paragraph-image"><div role="button" tabindex="0" class="nm nn fi no bg np"><div class="nd ne nf"><picture><source srcset="https://miro.medium.com/v2/resize:fit:640/format:webp/0*RRXAdbjJMMUTZ6OH 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/0*RRXAdbjJMMUTZ6OH 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/0*RRXAdbjJMMUTZ6OH 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/0*RRXAdbjJMMUTZ6OH 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/0*RRXAdbjJMMUTZ6OH 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/0*RRXAdbjJMMUTZ6OH 1100w, https://miro.medium.com/v2/resize:fit:1400/format:webp/0*RRXAdbjJMMUTZ6OH 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" type="image/webp" /><source data-testid="og" srcset="https://miro.medium.com/v2/resize:fit:640/0*RRXAdbjJMMUTZ6OH 640w, https://miro.medium.com/v2/resize:fit:720/0*RRXAdbjJMMUTZ6OH 720w, https://miro.medium.com/v2/resize:fit:750/0*RRXAdbjJMMUTZ6OH 750w, https://miro.medium.com/v2/resize:fit:786/0*RRXAdbjJMMUTZ6OH 786w, https://miro.medium.com/v2/resize:fit:828/0*RRXAdbjJMMUTZ6OH 828w, https://miro.medium.com/v2/resize:fit:1100/0*RRXAdbjJMMUTZ6OH 1100w, https://miro.medium.com/v2/resize:fit:1400/0*RRXAdbjJMMUTZ6OH 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" /></picture></div></div><figcaption class="nr fe ns nd ne nt nu be b bf z dt">Photo by <a class="af nv" href="https://unsplash.com/@grafiklee?utm_source=medium&amp;utm_medium=referral" rel="noopener ugc nofollow" target="_blank">Lee Jeffs</a> on <a class="af nv" href="https://unsplash.com/?utm_source=medium&amp;utm_medium=referral" rel="noopener ugc nofollow" target="_blank">Unsplash</a></figcaption></figure><p id="5f15" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj">My previous blog post <a class="af nv" href="https://medium.com/oracledevs/drcp-helps-apps-that-dont-use-a-connection-pool-5e19ecda36f0" rel="noopener">DRCP helps apps that don’t use a Connection Pool</a> showed an example which connected and disconnected frequently but didn’t use connection pooling. It explained how the app could benefit from Database Resident Connection Pooling (DRCP). This is because those frequent application disconnection calls let the database know when it is safe to reuse database server processes for other application users.</p><p id="5dd2" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj">The following example differs because a disconnection call happens only when a long-running application terminates. Pure DRCP won’t help because there is no connection-usage “boundary” to indicate when to reuse the database server processes. Luckily, Oracle Database 23ai “Implicit Connection Pooling” can figure it out.</p><p id="110a" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj">Let’s look at a demo. The following simple Python app <code class="cw nw nx ny nz b">long_run.py</code> opens a connection and then loops. In each iteration a query is executed and there is a sleep simulating user "think time" between queries. The connection is closed when the app finishes (handled by the end of the <code class="cw nw nx ny nz b">with</code> context block). This simulates a long-running app that holds onto a connection even when not executing a SQL statement:</p><pre class="ng nh ni nj nk oa nz ob bo oc ba bj"># long_run.pyimport os<br />import timeimport oracledb<br />import sample_env  # Contains credentials, see python-oracledb samples# Number of queries to execute in the life of this script<br />NUMSQLS = globals().get("NUMSQLS", 0)# Number of seconds to wait between executing SQL statements<br />SLEEPTIME = globals().get("SLEEPTIME", 0)# The name of the end "user", unique per execution of this script<br />APPUSERNAME = globals().get("APPUSERNAME", None)sql = """select unique sid||'-'||serial# as sidser,<br />                       current_timestamp as ct<br />         from v$session_connect_info<br />         where sid = sys_context('USERENV', 'SID')"""with oracledb.connect(<br />    user=sample_env.get_main_user(),<br />    password=sample_env.get_main_password(),<br />    dsn=sample_env.get_connect_string(),<br />) as connection:<br />    for i in range(NUMSQLS):<br />        with connection.cursor() as cursor:<br />            for s, d in cursor.execute(sql):<br />                print(f"{APPUSERNAME} sid-ser {s} at time {d}")<br />        time.sleep(SLEEPTIME)</pre><p id="5b32" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj">The application query gets the current time and the Session Identifier/Serial Number — this pair shows the database server process session in use. Each iteration’s query will output a line like:</p><pre class="ng nh ni nj nk oa nz ob bo oc ba bj">User01 sid-ser 407-62786 at time 2024-06-11 20:29:34.632666</pre><p id="b856" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj">The connection string is a simple one like <code class="cw nw nx ny nz b">localhost/orclpdb1</code> . There is no DRCP involved.</p><p id="a0b7" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj">A helper script, <code class="cw nw nx ny nz b">runner.py</code>, is used to simulate a number of users concurrently running <code class="cw nw nx ny nz b">long_run.py</code>. The helper script invokes <code class="cw nw nx ny nz b">long_run.py</code> 10 times (set in "<code class="cw nw nx ny nz b">NUMUSERS</code>") via the use of threads. Each invocation of <code class="cw nw nx ny nz b">long_run.py</code> is passed a unique "user name" e.g. <code class="cw nw nx ny nz b">User01</code> (via "<code class="cw nw nx ny nz b">APPUSERNAME</code>"), the number of SQL statements to execute ("<code class="cw nw nx ny nz b">NUMSQLS</code>"), and the sleep time ("<code class="cw nw nx ny nz b">SLEEPTIME</code>") between executions. The sleep time emulates the application user being idle and not executing SQL statements. The helper script is:</p><pre class="ng nh ni nj nk oa nz ob bo oc ba bj"># runner.pyimport threading<br />import timeimport sample_env  # Contains credentials, see python-oracledb samplesNUMUSERS = 10      # number of times to concurrently invoke long_run.pydef start_app(tn):<br />    app_globals = {<br />        "APPUSERNAME": "User{:02d}".format(tn + 1),  # Name of the "user" running long_run.py<br />        "NUMSQLS": 5,     # Number of queries to execute in the life of long_run.py<br />        "SLEEPTIME": 5,   # Number of seconds to sleep between SQL statements<br />    }<br />    exec(open("long_run.py").read(), app_globals)def start_workload():<br />    thread = []<br />    for i in range(NUMUSERS):<br />        t = threading.Thread(target=start_app, args=(i,))<br />        t.start()<br />        thread.append(t)for i in range(NUMUSERS):<br />        thread[i].join()if __name__ == "__main__":print(f"Using connection string: {sample_env.get_connect_string()}")start = time.time()<br />    start_workload()<br />    elapsed = time.time() - start<br />    print("All done!")<br />    print("Time {:04.2f} seconds".format(elapsed))</pre><p id="ad7e" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj">As coded, each <code class="cw nw nx ny nz b">long_run.py</code> process will run 5 queries with a sleep time of 5 seconds between each query. (In practice, your applications may stay open much longer). Add in a small amount of time for overheads, connecting, and executing statements gives a total expected end-to-end time of bit more than 25 seconds:</p><pre class="ng nh ni nj nk oa nz ob bo oc ba bj">$ python3 runner.py<br />Using connection string: localhost/orclpdb1<br />User01 sid-ser 407-62786 at time 2024-06-11 20:29:34.632666<br />User03 sid-ser 26-48119  at time 2024-06-11 20:29:34.802162<br />User02 sid-ser 172-37948 at time 2024-06-11 20:29:34.973973<br />User04 sid-ser 272-26116 at time 2024-06-11 20:29:35.146129<br />User05 sid-ser 398-8361  at time 2024-06-11 20:29:35.315068<br />User07 sid-ser 33-58745  at time 2024-06-11 20:29:35.485322<br />User08 sid-ser 154-64891 at time 2024-06-11 20:29:35.667774<br />User09 sid-ser 268-40439 at time 2024-06-11 20:29:35.837789<br />User10 sid-ser 408-62081 at time 2024-06-11 20:29:36.013276<br />User06 sid-ser 10-45069  at time 2024-06-11 20:29:36.189829<br />User01 sid-ser 407-62786 at time 2024-06-11 20:29:39.653528<br />User03 sid-ser 26-48119  at time 2024-06-11 20:29:39.821690<br />User02 sid-ser 172-37948 at time 2024-06-11 20:29:39.990345<br />User04 sid-ser 272-26116 at time 2024-06-11 20:29:40.162383<br />User05 sid-ser 398-8361  at time 2024-06-11 20:29:40.330363<br />User07 sid-ser 33-58745  at time 2024-06-11 20:29:40.503150<br />User08 sid-ser 154-64891 at time 2024-06-11 20:29:40.686834<br />User09 sid-ser 268-40439 at time 2024-06-11 20:29:40.854444<br />User10 sid-ser 408-62081 at time 2024-06-11 20:29:41.029533<br />User06 sid-ser 10-45069  at time 2024-06-11 20:29:41.206820<br />User01 sid-ser 407-62786 at time 2024-06-11 20:29:44.666896<br />User03 sid-ser 26-48119  at time 2024-06-11 20:29:44.835387<br />User02 sid-ser 172-37948 at time 2024-06-11 20:29:45.005330<br />User04 sid-ser 272-26116 at time 2024-06-11 20:29:45.177302<br />User05 sid-ser 398-8361  at time 2024-06-11 20:29:45.343248<br />User07 sid-ser 33-58745  at time 2024-06-11 20:29:45.520129<br />User08 sid-ser 154-64891 at time 2024-06-11 20:29:45.704843<br />User09 sid-ser 268-40439 at time 2024-06-11 20:29:45.868719<br />User10 sid-ser 408-62081 at time 2024-06-11 20:29:46.046426<br />User06 sid-ser 10-45069  at time 2024-06-11 20:29:46.225250<br />User01 sid-ser 407-62786 at time 2024-06-11 20:29:49.679691<br />User03 sid-ser 26-48119  at time 2024-06-11 20:29:49.848716<br />User02 sid-ser 172-37948 at time 2024-06-11 20:29:50.021498<br />User04 sid-ser 272-26116 at time 2024-06-11 20:29:50.191881<br />User05 sid-ser 398-8361  at time 2024-06-11 20:29:50.359139<br />User07 sid-ser 33-58745  at time 2024-06-11 20:29:50.542895<br />User08 sid-ser 154-64891 at time 2024-06-11 20:29:50.715070<br />User09 sid-ser 268-40439 at time 2024-06-11 20:29:50.880684<br />User10 sid-ser 408-62081 at time 2024-06-11 20:29:51.062274<br />User06 sid-ser 10-45069  at time 2024-06-11 20:29:51.245149<br />User01 sid-ser 407-62786 at time 2024-06-11 20:29:54.694733<br />User03 sid-ser 26-48119  at time 2024-06-11 20:29:54.866731<br />User02 sid-ser 172-37948 at time 2024-06-11 20:29:55.038168<br />User04 sid-ser 272-26116 at time 2024-06-11 20:29:55.206117<br />User05 sid-ser 398-8361  at time 2024-06-11 20:29:55.372266<br />User07 sid-ser 33-58745  at time 2024-06-11 20:29:55.560076<br />User08 sid-ser 154-64891 at time 2024-06-11 20:29:55.730851<br />User09 sid-ser 268-40439 at time 2024-06-11 20:29:55.899642<br />User10 sid-ser 408-62081 at time 2024-06-11 20:29:56.078866<br />User06 sid-ser 10-45069  at time 2024-06-11 20:29:56.260751<br />All done!<br />Time 26.85 seconds</pre><p id="0c72" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj">The important point is that each of the 10 processes will open a connection and keep it open for the duration the <code class="cw nw nx ny nz b">long_run.py</code> app run. This is shown by each user script always executing its queries with the same session identifier/serial number combination. For example <code class="cw nw nx ny nz b">User01</code> always uses <code class="cw nw nx ny nz b">407-62786</code>. This is 10 connections open all the time, each of which has a corresponding server process and session memory consuming database host resources.</p><h1 id="1489" class="oj oe gt be ok ol om on oo op oq or os ot ou ov ow ox oy oz pa pb pc pd pe pf bj">Oracle Database 23ai Implicit Connection Pooling</h1><p id="8c63" class="pw-post-body-paragraph mf mg gt mh b mi pg mk ml mm ph mo mp mq pi ms mt mu pj mw mx my pk na nb nc gm bj">Implicit Connection Pooling is an Oracle Database 23ai feature that makes use of Database Resident Connection Pooling to share database server processes and session memory. It is supported by the popular Oracle Database drivers, including <a class="af nv" href="https://pypi.org/project/oracledb/" rel="noopener ugc nofollow" target="_blank">python-oracledb</a>, <a class="af nv" href="https://www.npmjs.com/package/oracledb" rel="noopener ugc nofollow" target="_blank">node-oracledb</a> and JDBC.</p><p id="86f0" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj">Implicit Connection Pooling is suitable for applications that hold onto connections when not doing database work. This includes applications which implement their own connection pool solution holding the underlying connections to the database open for the life of the pool.</p><p id="4f9d" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj">Implicit Connection Pooling works by transparently recognizing the boundary when an application isn’t using an open connection. It then lets another application connection use the server process and session memory of the first (currently idle) connection. When the first application subsequently initiates another database request, a free database server process is allocated back to it and the application continues without knowing about the temporary ‘theft’ of the server process. No application changes are needed. The database’s resources are shared, allowing greater scalability.</p><p id="8c51" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj">Implicit Connection Pooling differs from pure DRCP because the mapping and unmapping of database server processes is done implicitly by Oracle. With pure DRCP, the mapping and unmapping only happens when the application initiates get-connection and close-connection calls.</p><p id="5ba9" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj">Because <code class="cw nw nx ny nz b">long_run.py</code> only has one open/close pair (the close is internally done at the end of the <code class="cw nw nx ny nz b">with</code> context), it is an ideal candidate for Implicit Connection Pooling. All that is needed is to start DRCP in the database, change the connection string to use a DRCP pooled server, and additionally set a <code class="cw nw nx ny nz b">POOL_BOUNDARY</code> parameter to the connection string. The application code is not modified. Re-running the demo gives the output:</p><pre class="ng nh ni nj nk oa nz ob bo oc ba bj">$ python3 runner.py<br />Using connection string: localhost/orclpdb1:pooled?pool_boundary=statement<br />User01 sid-ser 399-25678 at time 2024-06-11 20:28:46.803668<br />User02 sid-ser 399-25678 at time 2024-06-11 20:28:46.830118<br />User05 sid-ser 399-25678 at time 2024-06-11 20:28:46.840759<br />User04 sid-ser 399-25678 at time 2024-06-11 20:28:46.867337<br />User03 sid-ser 152-55977 at time 2024-06-11 20:28:46.908656<br />User08 sid-ser 152-55977 at time 2024-06-11 20:28:46.978751<br />User09 sid-ser 152-55977 at time 2024-06-11 20:28:47.045773<br />User06 sid-ser 152-55977 at time 2024-06-11 20:28:47.106757<br />User10 sid-ser 152-55977 at time 2024-06-11 20:28:47.169244<br />User07 sid-ser 152-55977 at time 2024-06-11 20:28:47.229357<br />User01 sid-ser 152-55977 at time 2024-06-11 20:28:51.844053<br />User02 sid-ser 399-25678 at time 2024-06-11 20:28:51.844449<br />User05 sid-ser 152-55977 at time 2024-06-11 20:28:51.855879<br />User04 sid-ser 152-55977 at time 2024-06-11 20:28:51.883601<br />User03 sid-ser 152-55977 at time 2024-06-11 20:28:51.940661<br />User08 sid-ser 152-55977 at time 2024-06-11 20:28:51.990124<br />User09 sid-ser 152-55977 at time 2024-06-11 20:28:52.058879<br />User06 sid-ser 152-55977 at time 2024-06-11 20:28:52.120180<br />User10 sid-ser 152-55977 at time 2024-06-11 20:28:52.182709<br />User07 sid-ser 152-55977 at time 2024-06-11 20:28:52.243295<br />User01 sid-ser 152-55977 at time 2024-06-11 20:28:56.874489<br />User02 sid-ser 399-25678 at time 2024-06-11 20:28:56.874487<br />User04 sid-ser 399-25678 at time 2024-06-11 20:28:56.895112<br />User03 sid-ser 399-25678 at time 2024-06-11 20:28:56.954245<br />User05 sid-ser 277-27334 at time 2024-06-11 20:28:56.969050<br />User08 sid-ser 277-27334 at time 2024-06-11 20:28:56.997923<br />User09 sid-ser 277-27334 at time 2024-06-11 20:28:57.072845<br />User06 sid-ser 277-27334 at time 2024-06-11 20:28:57.131504<br />User10 sid-ser 277-27334 at time 2024-06-11 20:28:57.195656<br />User07 sid-ser 277-27334 at time 2024-06-11 20:28:57.257700<br />User01 sid-ser 399-25678 at time 2024-06-11 20:29:01.903889<br />User02 sid-ser 277-27334 at time 2024-06-11 20:29:01.903889<br />User04 sid-ser 152-55977 at time 2024-06-11 20:29:01.910282<br />User03 sid-ser 152-55977 at time 2024-06-11 20:29:01.968523<br />User05 sid-ser 152-55977 at time 2024-06-11 20:29:01.997715<br />User08 sid-ser 152-55977 at time 2024-06-11 20:29:02.011130<br />User09 sid-ser 152-55977 at time 2024-06-11 20:29:02.086866<br />User06 sid-ser 152-55977 at time 2024-06-11 20:29:02.139241<br />User10 sid-ser 152-55977 at time 2024-06-11 20:29:02.209716<br />User07 sid-ser 152-55977 at time 2024-06-11 20:29:02.271144<br />User01 sid-ser 152-55977 at time 2024-06-11 20:29:06.940760<br />User02 sid-ser 277-27334 at time 2024-06-11 20:29:06.940760<br />User04 sid-ser 399-25678 at time 2024-06-11 20:29:06.940760<br />User03 sid-ser 399-25678 at time 2024-06-11 20:29:06.982961<br />User05 sid-ser 399-25678 at time 2024-06-11 20:29:07.010853<br />User08 sid-ser 399-25678 at time 2024-06-11 20:29:07.023677<br />User09 sid-ser 399-25678 at time 2024-06-11 20:29:07.102189<br />User06 sid-ser 399-25678 at time 2024-06-11 20:29:07.152508<br />User10 sid-ser 399-25678 at time 2024-06-11 20:29:07.223001<br />User07 sid-ser 399-25678 at time 2024-06-11 20:29:07.284733<br />All done!<br />Time 25.96 seconds</pre><p id="7e72" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj">This shows server process and session memory being reused across different users’ queries, for example the first two lines have the same session identifier/serial number:</p><pre class="ng nh ni nj nk oa nz ob bo oc ba bj">User01 sid-ser 399-25678 at time 2024-06-11 20:28:46.803668<br />User02 sid-ser 399-25678 at time 2024-06-11 20:28:46.830118</pre><p id="6990" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj">If you crunch the output, you can see that in this run only three servers are used for all queries being executed. The session identifier/serial number pairs are:</p><pre class="ng nh ni nj nk oa nz ob bo oc ba bj">152-55977<br />277-27334<br />399-25678</pre><p id="f841" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj">This is many fewer than the ten servers needed without Implicit Connection Pooling. Your absolute results will be different, depending on factors like timing.</p><p id="744c" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj">The total time difference between the two runs is close but in this small test isn’t significant for comparison. In general, because Implicit Connection Pooling shares resources and the Oracle stack has to do some extra work, it’s possible the total time will be slower when moving to Implicit Connection Pooling — if the difference is even accurately measurable. This would depend on how frequently applications execute SQL. However, the benefit is that the database tier uses less memory due to the lower number of server processes, so it may be more efficient — and it certainly can handle more user connections from other applications.</p><h1 id="b11c" class="oj oe gt be ok ol om on oo op oq or os ot ou ov ow ox oy oz pa pb pc pd pe pf bj">Configuring Implicit Connection Pooling</h1><p id="aeb9" class="pw-post-body-paragraph mf mg gt mh b mi pg mk ml mm ph mo mp mq pi ms mt mu pj mw mx my pk na nb nc gm bj">DRCP provides the configurable pool of database server processes used by Implicit Connection Pooling. DRCP needs to be enabled, monitored, and tuned in the database, see the technical brief <a class="af nv" href="https://www.oracle.com/docs/tech/drcp-technical-brief.pdf" rel="noopener ugc nofollow" target="_blank">Extreme Oracle Database Connection Scalability with Database Resident Connection Pooling</a>.</p><p id="31f9" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj">On the application side, your connection string simply needs to request a DRCP pooled server, e.g. with “<code class="cw nw nx ny nz b">:pooled</code>" or "<code class="cw nw nx ny nz b">(SERVER=POOLED)</code>". It additionally needs to contain a new <code class="cw nw nx ny nz b">POOL_BOUNDARY</code> parameter. The connection string used in this blog post was an Easy Connect string <code class="cw nw nx ny nz b">localhost/orclpdb1:pooled?pool_boundary=statement</code>. In a tnsnames.ora file, an equivalent connect descriptor would contain "...<code class="cw nw nx ny nz b">(POOL_BOUNDARY=STATEMENT)</code>..."</p><p id="870b" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj">The <code class="cw nw nx ny nz b">POOL_BOUNDARY</code> parameter can have the value <code class="cw nw nx ny nz b">STATEMENT</code> or <code class="cw nw nx ny nz b">TRANSACTION</code>:</p><ul class=""><li id="66af" class="mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc pl pm pn bj"><strong class="mh gu">STATEMENT</strong>: a connection is released back to the DRCP connection pool when the connection is implicitly stateless, i.e. when there are no active cursors in the connection (all the rows of the cursors have been internally fetched), no active transactions, no temporary tables, and no temporary LOBs.</li><li id="a932" class="mf mg gt mh b mi po mk ml mm pp mo mp mq pq ms mt mu pr mw mx my ps na nb nc pl pm pn bj"><strong class="mh gu">TRANSACTION</strong>: a connection is released back to the DRCP connection pool when a commit or rollback is initiated by the app. It is recommended to not enable any driver “autocommit” setting when using Implicit Connection Pooling. If you do, then you will be unable to fetch any data that requires multiple round-trips to the database, such as streaming LOB data.</li></ul><p id="497e" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj">In line with standard DRCP recommendations for security, you should add a <code class="cw nw nx ny nz b">POOL_CONNECTION_CLASS</code> parameter to the connection string, using the same value for all applications that are alike, for example:</p><p id="cd0c" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj"><code class="cw nw nx ny nz b">localhost/orclpdb1:pooled?pool_boundary=statement&amp;pool_connection_class=myappname</code></p><p id="d2e7" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj">The DRCP “purity” used by Implicit Connection Pooling defaults to <code class="cw nw nx ny nz b">SELF</code>, which allows reuse of the server process session memory. Adding the connection string parameter <code class="cw nw nx ny nz b">POOL_PURITY=NEW</code> will change this and cause each use of a connection to recreate the session memory.</p><p id="fb51" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj">You can optionally create a PL/SQL package <code class="cw nw nx ny nz b">ORA_CPOOL_STATE</code> with procedures to get and reset connection session state, see the <a class="af nv" href="https://docs.oracle.com/en/database/oracle/oracle-database/23/adfns/performance-and-scalability.html#GUID-4E3B5F7D-9147-4F9B-9C1A-75446E2792E5" rel="noopener ugc nofollow" target="_blank">Oracle Call Interface documentation</a>.</p><h1 id="16ad" class="oj oe gt be ok ol om on oo op oq or os ot ou ov ow ox oy oz pa pb pc pd pe pf bj">When not to use Implicit Connection Pooling</h1><p id="4745" class="pw-post-body-paragraph mf mg gt mh b mi pg mk ml mm ph mo mp mq pi ms mt mu pj mw mx my pk na nb nc gm bj">If you can restructure your application to use an Oracle-provided driver connection pool, this can be the most efficient outcome. A driver connection pool provides resource sharing, and provides Oracle Database high availability features. Using a driver connection pool (such as the python-oracledb <a class="af nv" href="https://python-oracledb.readthedocs.io/en/latest/user_guide/connection_handling.html#connection-pooling" rel="noopener ugc nofollow" target="_blank">connection pool</a> or node-oracledb <a class="af nv" href="https://node-oracledb.readthedocs.io/en/latest/user_guide/connection_handling.html#connection-pooling" rel="noopener ugc nofollow" target="_blank">connection pool</a>) is often best suited for multi-user applications, but even single user applications that infrequently use connections can benefit from them. The blog post <a class="af nv" href="https://medium.com/oracledevs/desktop-applications-with-node-oracledb-and-electron-b45db49653c7" rel="noopener">Desktop applications with node-oracledb and electron</a> shows one such scenario. If an application is efficiently using an Oracle application connection pool, and getting and releasing connections frequently, then Implicit Connection Pooling provides no benefit.</p><p id="b231" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj">If your application can’t be changed to use an Oracle driver connection pool, but the app opens and closes connections frequently, then you may be able to benefit from DRCP directly without enabling Implicit Connection Pooling. See my blog post <a class="af nv" href="https://medium.com/oracledevs/drcp-helps-apps-that-dont-use-a-connection-pool-5e19ecda36f0" rel="noopener">DRCP helps apps that don’t use a Connection Pool</a>.</p><p id="97ca" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj">At an application level, there are some cases where Implicit Connection Pooling isn’t a good match. As you can see from the example in this post, the session identifier and serial number that a “user” saw for each of their SQL statements varied during the life of that user’s script. So if your app relies on the values not changing, then Implicit Connection Pooling isn’t a good fit.</p><p id="23cb" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj">Another example of a fit that may have issues, is using a statement boundary of TRANSACTION when multiple cursors are in use by the application, or when you are streaming LOBs. In this scenario any application commit can invalidate any open cursors, and also prevent LOB streaming.</p><p id="da62" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj">You should thoroughly test your application when using Implicit Connection Pooling to ensure that the internal reuse of database servers and sessions does not cause any problems.</p><h1 id="62fb" class="oj oe gt be ok ol om on oo op oq or os ot ou ov ow ox oy oz pa pb pc pd pe pf bj">Conclusion</h1><p id="5455" class="pw-post-body-paragraph mf mg gt mh b mi pg mk ml mm ph mo mp mq pi ms mt mu pj mw mx my pk na nb nc gm bj">Implicit Connection Pooling allows applications that hold connections open for a long time to share their database server processes and session memory. This reduces memory pressure on the database host, and makes the overall system more scalable. Implicit Connection Pooling can be helpful for apps that open single connections, or that implement their own connection pooling solution instead of using an Oracle-provided driver connection pool. It is supported by the popular Oracle Database drivers.</p><p id="c399" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj">This post discussed how Implicit Connection Pooling makes use of DRCP. It can additionally make use of <a class="af nv" href="https://docs.oracle.com/en/database/oracle/oracle-database/23/admin/managing-processes.html#GUID-E0032017-03B1-4F14-AF9B-BCC87C982DA8" rel="noopener ugc nofollow" target="_blank">PRCP</a>, which is available when your system uses <a class="af nv" href="https://download.oracle.com/ocomdocs/global/CMAN_TDM_Oracle_DB_Connection_Proxy_for_scalable_apps.pdf" rel="noopener ugc nofollow" target="_blank">Oracle Connection Manager in Traffic Director Mode</a>.</p><p id="27c2" class="pw-post-body-paragraph mf mg gt mh b mi mj mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc gm bj">For a video on Implicit Connection Pooling see <a class="af nv" href="https://www.youtube.com/watch?v=MjPlTpJnZZ0" rel="noopener ugc nofollow" target="_blank">Effortless Connection Management with Implicit Pooling in Oracle Database 23c</a> by my colleague Sharad Chandran R.</p><h1 id="23dd" class="oj oe gt be ok ol om on oo op oq or os ot ou ov ow ox oy oz pa pb pc pd pe pf bj">References</h1><ul class=""><li id="9b19" class="mf mg gt mh b mi pg mk ml mm ph mo mp mq pi ms mt mu pj mw mx my pk na nb nc pl pm pn bj">Video: <a class="af nv" href="https://www.youtube.com/watch?v=MjPlTpJnZZ0" rel="noopener ugc nofollow" target="_blank">Effortless Connection Management with Implicit Pooling in Oracle Database 23c</a> (video).</li><li id="83db" class="mf mg gt mh b mi po mk ml mm pp mo mp mq pq ms mt mu pr mw mx my ps na nb nc pl pm pn bj">Python-oracledb Documentation: <a class="af nv" href="https://python-oracledb.readthedocs.io/en/latest/user_guide/connection_handling.html#implicit-connection-pooling" rel="noopener ugc nofollow" target="_blank">Implicit Connection Pooling</a>.</li><li id="b120" class="mf mg gt mh b mi po mk ml mm pp mo mp mq pq ms mt mu pr mw mx my ps na nb nc pl pm pn bj">Node-oracledb documentation: <a class="af nv" href="https://node-oracledb.readthedocs.io/en/latest/user_guide/connection_handling.html#implicit-connection-pooling" rel="noopener ugc nofollow" target="_blank">Implicit Connection Pooling</a>.</li><li id="7fef" class="mf mg gt mh b mi po mk ml mm pp mo mp mq pq ms mt mu pr mw mx my ps na nb nc pl pm pn bj">Blog post: <a class="af nv" rel="noopener" href="https://medium.com/always-use-connection-pools-and-how-909bc2c65444">Always Use Connection Pools — and How</a>.</li><li id="8f78" class="mf mg gt mh b mi po mk ml mm pp mo mp mq pq ms mt mu pr mw mx my ps na nb nc pl pm pn bj">Blog post: <a class="af nv" href="https://medium.com/oracledevs/drcp-helps-apps-that-dont-use-a-connection-pool-5e19ecda36f0" rel="noopener">DRCP helps apps that don’t use a Connection Pool</a></li><li id="9886" class="mf mg gt mh b mi po mk ml mm pp mo mp mq pq ms mt mu pr mw mx my ps na nb nc pl pm pn bj">Technical Brief: <a class="af nv" href="https://www.oracle.com/docs/tech/drcp-technical-brief.pdf" rel="noopener ugc nofollow" target="_blank">Extreme Oracle Database Connection Scalability with Database Resident Connection Pooling (DRCP)</a>.</li><li id="b24d" class="mf mg gt mh b mi po mk ml mm pp mo mp mq pq ms mt mu pr mw mx my ps na nb nc pl pm pn bj">Technical Brief: <a class="af nv" href="https://download.oracle.com/ocomdocs/global/CMAN_TDM_Oracle_DB_Connection_Proxy_for_scalable_apps.pdf" rel="noopener ugc nofollow" target="_blank">CMAN-TDM — An Oracle Database connection proxy for scalable and highly available applications</a>.</li></ul></div>]]></description>
      <link>https://medium.com/oracledevs/implicit-connection-pooling-when-connections-overload-your-database-3fe7c59acae2?source=rss-adc937c3a9d------2</link>
      <guid>https://medium.com/oracledevs/implicit-connection-pooling-when-connections-overload-your-database-3fe7c59acae2?source=rss-adc937c3a9d------2</guid>
      <pubDate>Tue, 18 Jun 2024 03:01:00 +0200</pubDate>
    </item>
    <item>
      <title><![CDATA[Updating (PHP) packages to ReactPHP Promise v3, and test your types with PHPStan - Cees-Jan Kiewiet]]></title>
      <description><![CDATA[<p><img alt="Cees-Jan" class="img-circle" src="https://blog.wyrihaximus.net/images/photo-cj.jpg" width="50px" height="50px" /><a href="https://plus.google.com/116291745551237181952?rel=author" target="_blank" itemprop="author" itemscope="itemscope" itemtype="http://schema.org/Person">Cees-Jan Kiewiet</a></p><p><time itemprop="datePublished" datetime="2024-06-18T00:00:00+00:00">18 June 2024</time> - <a href="https://github.com/WyriHaximus/blog.wyrihaximus.net/blob/master/source/_posts/2024-06-18-updating-php-packages-to-reactphp-promise-v3--and-test-your-types-with-phpstan.markdown">Post source at 🐙</a></p><h4>Updating (PHP) packages to ReactPHP Promise v3, and test your types with PHPStan</h4><p>With version 3, react/promise adds template types to communicate what kind of data the promise will hold once resolved. Add react/async 4.2 with https://github.com/reactphp/async/pull/40 to that and return type hints are a thing and both PHPStan and Psalm will understand them.</p><p><img src="https://blog.wyrihaximus.net/images/posts/updating-php-packages-to-reactphp-promise-v3--and-test-your-types-with-phpstan.jpg" alt="Photo of coloured lab veils" /></p><blockquote>
<p><a href="https://www.pexels.com/photo/colorful-liquids-in-test-tubes-8325719/">Photo by Kindel Media</a></p>
</blockquote><p>These past few weeks I’ve been working on upgrading all my PHP packages to 8.2+ and the update for ReactPHP packages also will include Promise v3. This means that if you want to use any of my packages with Promise v3, you’ll need to be on PHP 8.2. (With sponsorships that number can be lowered, but only to a certain point.)</p><p>During the work on https://github.com/reactphp/promise/pull/247 it became apparent that we needed a way to validate our expected return types. PHPStan provides a way to do that with the <code>PHPStan\Testing\assertType</code>.</p><p>Let’s assume we have a function named <code>futurePromise</code> that returns a promise which resolves when the event loop has done another tick. The implementation is pretty simple:</p><pre class="php">/**
 * Promise that resolves once future tick is called.
 *
 * @param mixed $value Value to return on resolve.
 */
function futurePromise($value = null): PromiseInterface
{
    $deferred = new Deferred();
    Loop::futureTick(static function () use ($deferred, $value): void {
        $deferred-&gt;resolve($value);
    });
    return $deferred-&gt;promise();
}
</pre><p>This is a pretty straightforward implementation: * Created deferred * Schedule tick * Return promise * One tick happens resolve the promise with the value passed into the function</p><p>To make it communicate the type the promise will hold, it had to be changed to:</p><pre class="php">/**
 * Promise that resolves once future tick is called.
 * 
 * @param T $value Value to return on resolve.
 *
 * @return PromiseInterface&lt;T&gt;
 *
 * @template T
 * @phpstan-ignore-next-line
 */
function futurePromise(mixed $value = null): PromiseInterface
{
    /** @var Deferred&lt;T&gt; $deferred */
    $deferred = new Deferred();
    Loop::futureTick(static function () use ($deferred, $value): void {
        $deferred-&gt;resolve($value);
    });
    return $deferred-&gt;promise();
}
</pre><p>And we feed PHPStan these two tests for type safety.</p><pre class="php">&lt;?php
declare(strict_types=1);
use function PHPStan\Testing\assertType;
use function WyriHaximus\React\futurePromise;
assertType('React\Promise\PromiseInterface&lt;bool&gt;', futurePromise(true));
assertType('React\Promise\PromiseInterface&lt;null&gt;', futurePromise());
</pre><p>In total that is 4 changed lines and one new file in this package (ignoring the PHPStan ignore there for the argument with default value). To ensure PHPStan (and Psalm) understand whatever you put into the first argument, comes out through the promise. It works by telling PHPStan that <code>$value</code> is of type T, and that we return it by wrapping it into a <code>promise&lt;T&gt;</code>. There is a lot more happening behind the scenes, which is why we had to point out that <code>$deferred</code> is <code>Deferred&lt;T&gt;</code>.</p><p>Ultimately, we want to get to this, but for now promise typing is a major first step:</p><pre class="php">&lt;?php
declare(strict_types=1);
use function PHPStan\Testing\assertType;
use function WyriHaximus\React\futurePromise;
assertType('bool', futurePromise(true));
assertType('null', futurePromise());
</pre><p>This will be done by using <code>await()</code> inside <code>futurePromise</code> in this case. Or as close as possible to the promise returned. But for this post we’re focusing on adding it to a package.</p><p>While the removal of <code>done()</code> and erroring on handled rejections might be the most impactful changes in how <code>react/promise</code> affects users directly. The added type safety's value isn’t to underestimated. PHPStan’s <code>assertType</code> function is incredible valuable to test and proof your functions/methods return types. I strongly encourage all package owners out there to add these tests if you use <code>@template</code> types in your packages.</p><hr /><p> <a class="FlattrButton c1" title="Updating (PHP) packages to ReactPHP Promise v3, and test your types with PHPStan" data-flattr-uid="WyriHaximus" data-flattr-tags="text, opensource" data-flattr-category="text" data-flattr-language="en_GB" data-flattr-button="compact" href="https://blog.wyrihaximus.net/2024/06/updating-php-packages-to-reactphp-promise-v3--and-test-your-types-with-phpstan/">With version 3, react/promise adds template types to communicate what kind of data the promise will hold once resolved. Add react/async 4.2 with https://github.com/reactphp/async/pull/40 to that and return type hints are a thing and both PHPStan and Psalm will understand them. Photo by Kindel Media</a></p>]]></description>
      <link>https://blog.wyrihaximus.net/2024/06/updating-php-packages-to-reactphp-promise-v3--and-test-your-types-with-phpstan/</link>
      <guid>https://blog.wyrihaximus.net/2024/06/updating-php-packages-to-reactphp-promise-v3--and-test-your-types-with-phpstan/</guid>
      <pubDate>Tue, 18 Jun 2024 02:00:00 +0200</pubDate>
    </item>
    <item>
      <title><![CDATA[Apache+PHP: Content-Length header is missing - Christian Weiske]]></title>
      <description><![CDATA[<p>I received a photo in the <a href="https://conversations.im/">Conversations</a> XMPP app on my Android phone, but the image was not shown. Instead I got a message</p><blockquote lang="de"><div>Bildgröße auf xmpp-files.cweiske.de prüfen</div></blockquote>
<p>which translates to</p>
<blockquote><div>Checking image size on xmpp-files.cweiske.de</div></blockquote>
<p>The other XMPP client <a href="https://dino.im/">Dino</a> showed the images, though.</p>
<p>In <a href="https://codeberg.org/iNPUTmice/Conversations/issues/240" title="Issue with download image #240">Conversations bug report #240</a> it was observed that the <code>Content-Length</code> header was missing, and my server exhibited the same problem:</p>
<pre>$ curl -I 'https://xmpp-files.cweiske.de/share_v2.php/23/42.jpg
HTTP/1.1 200 OK
Date: Sat, 08 Jun 2024 12:38:47 GMT
Server: Apache/2.4.59 (Debian)
Access-Control-Allow-Methods: GET, PUT, OPTIONS
Access-Control-Allow-Headers: Content-Type
Access-Control-Max-Age: 7200
Access-Control-Allow-Origin: *
Content-Security-Policy: "default-src 'none'"
X-Content-Security-Policy: "default-src 'none'"
X-WebKit-CSP: "default-src 'none'"
Content-Type: image/jpeg</pre>
<p>No <code>Content-Length</code>. I'm using the <a href="https://modules.prosody.im/mod_http_upload_external">mod_http_upload_external</a> Prosody module for file uploads together with the <code>share_v2.php</code> provided by it. That PHP script does set a <code>Content-Length</code> header, but nobody receives it!</p>
<p>Even a PHP script that only sends out a <code>Content-Length</code> header does not work:</p>
<pre class="php c1">&lt;?php
header('X-Test: 23');
header('Content-Length: 42');</pre>
<pre>$ curl -I https://xmpp-files.cweiske.de/test.php
HTTP/1.1 200 OK
Date: Sat, 08 Jun 2024 13:18:34 GMT
Server: Apache/2.4.59 (Debian)
X-Test: 23
Content-Type: text/html; charset=UTF-8</pre>
<p>The header is missing.</p>
<h2 id="cause">The cause<a class="anchorlink" href="http://cweiske.de/tagebuch/content-length-header-missing.htm#cause">​</a></h2>
<p>Then I found Apache bug report <a href="https://bz.apache.org/bugzilla/show_bug.cgi?id=68973">#68973: Content-Length header missing in 2.4.59 is a breaking change</a> which explained the symptom I experienced:</p>
<p><a href="https://downloads.apache.org/httpd/CHANGES_2.4.59">Apache version 2.4.59</a> fixed security issue <a href="https://cve.mitre.org/cgi-bin/cvename.cgi?name=2024-24795">CVE-2024-24795</a> by preventing CGI-like scripts (such as PHP) from sending out <code>Content-Length</code> headers.</p>
<p>A new environment variable <a href="https://httpd.apache.org/docs/current/env.html#cgilike">ap_trust_cgilike_cl</a> was introduced that restores to the old behavior.</p>
<h2 id="solution">Solution<a class="anchorlink" href="http://cweiske.de/tagebuch/content-length-header-missing.htm#solution">​</a></h2>
<p>I re-enabled the Content-Length header in my PHP applications by creating an apache configuration file</p>
<div class="pre-title"><code>/etc/apache2/conf-available/cweiske-content-length.conf</code></div>
<pre>SetEnv ap_trust_cgilike_cl 1</pre>
<p>enabling it and restarting apache2:</p>
<pre class="bash c1">$ a2enconf cweiske-content-length
$ systemctl reload apache2</pre>]]></description>
      <link>http://cweiske.de/tagebuch/content-length-header-missing.htm</link>
      <guid>http://cweiske.de/tagebuch/content-length-header-missing.htm</guid>
      <pubDate>Sat, 08 Jun 2024 15:09:00 +0200</pubDate>
    </item>
    <item>
      <title><![CDATA[Introducing Bag: Immutable Values Objects for PHP - Davey Shafik]]></title>
      <description><![CDATA[<pre>error code: 520</pre>]]></description>
      <link>https://www.daveyshafik.com/archives/70826-introducing-bag-immutable-values-objects-for-php.html</link>
      <guid>https://www.daveyshafik.com/archives/70826-introducing-bag-immutable-values-objects-for-php.html</guid>
      <pubDate>Sun, 19 May 2024 04:15:00 +0200</pubDate>
    </item>
    <item>
      <title><![CDATA[Initializing ZendHQ JobQueue During Application Deployment - Matthew Weier O'Phinney]]></title>
      <description><![CDATA[<p>In the past few years, I've transitioned from engineering into product management at <a href="https://www.zend.com">Zend</a>, and it's been a hugely rewarding experience to be able to toss ideas over the fence to my own engineering team, and have them do all the fiddly tricky bits of actually implementing them!</p><p>Besides packaging long-term support versions of PHP, we also are publishing a product called ZendHQ. This is a combination of a PHP extension, and an independent service that PHP instances communicate with to do things like monitoring and queue management.</p><p>It's this latter I want to talk about a bit here, as (a) I think it's a really excellent tool, and (b) in using it, I've found some interesting patterns for prepping it during deployment.</p><h5>What does it do?</h5><p>ZendHQ's JobQueue feature provides the ability to defer work, schedule it to process at a future date and time, and to schedule recurring work. Jobs themselves can be either command-line processes, or webhooks that JobQueue will call when the job runs.</p><p>Why would you use this over, say, a custom queue runner managed by supervisord, or a tool like Beanstalk, or cronjobs?</p><p>There's a few reasons:</p><ul><li>Queue management and insight. Most of these tools do not provide any way to inspect what jobs are queued, running, or complete, or even if they failed. You can <em>add</em> those features, but they're not built in.</li>
<li>If you are using monitoring tools with PHP... queue workers used with these tools generally cannot be monitored. If I run my jobs as web jobs, these can run within the same cluster and communicate to the same ZendHQ instance, giving me monitoring and code traces for free.</li>
<li>Speaking of using web workers, this means I can also re-use technologies that are stable and provide worker management that I already know: php-fpm and mod_php. This is less to learn, and something I already have running.</li>
<li>Retries. JobQueue allows you to configure the ability to retry a job, and how long to wait between retries. A lot of jobs, particularly if they rely on other web services, will have transient failures, and being able to retry can make them far more reliable.</li>
</ul><h5>So, what about queue warmup?</h5><p>When using recurring jobs, you'll (a) want to ensure your queue is defined, and (b) define any recurring jobs at application deployment. You don't want to be checking on each and every request to see if the queues are present, or if the recurring jobs are present. Ideally, this should only happen on application deployment.</p><p>When deploying my applications, I generally have some startup scripts I fire off. Assuming that the PHP CLI is configured with the ZendHQ extension and can reach the ZendHQ instance, these scripts can (a) check for and create queues, and (b) check for and create recurring jobs.</p><p>As a quick example:</p><pre class="language-php hljs php" data-lang="php">use ZendHQ\JobQueue\HTTPJob;
use ZendHQ\JobQueue\JobOptions;
use ZendHQ\JobQueue\JobQueue;
use ZendHQ\JobQueue\Queue;
use ZendHQ\JobQueue\QueueDefinition;
use ZendHQ\JobQueue\RecurringSchedule;
$jq = new ZendHQ\JobQueue();
// Lazily create the queue "mastodon"
$queue = $jq-&gt;hasQueue('mastodon')
    ? $jq-&gt;getQueue('mastodon')
    ? $jq-&gt;addQueue('mastodon', new QueueDefinition(
        QueueDefinition::PRIORITY_NORMAL,
        new JobOptions(
            JobOptions::PRIORITY_NORMAL,
            60, // timeout
            3, // allowed retries
            30, // retry wait time
            JobOptions::PERSIST_OUTPUT_ERROR,
            false, // validate SSL
    ));
// Look for jobs named "timeline"
$jobs = $queue-&gt;getJobsByName('timeline');
if (count($jobs) === 0) {
    // Job does not exist; create it
    $job = new HTTPJob('http://worker/mastodon/timeline', HTTPJob::HTTP_METHOD_POST);
    $job-&gt;setName('timeline');
    $job-&gt;addHeader('Content-Type', 'application/my-site-jq+json');
    $job-&gt;setRawBody(json_encode([
        'type' =&gt; MyApp\Mastodon\Timeline::class,
        'data' =&gt; [ /* ... */ ],
    ]);
    // Schedule to run every 15 minutes
    $queue-&gt;scheduleJob($job, new RecurringSchedule('* */15 * * * *'));
}
</pre><p>That's literally it.</p><p>The takeaway points:</p><ul><li>You can check for an existing queue and use it, and only define it if it's not there. You could also decide to suspend the queue and delete it before creating it, if you know that the existing jobs will not run with the current deployment.</li>
<li>If you give a job a name (you don't actually have to, but it helps you identify related jobs far easier if you do), you can search for it. In the example above, if I find any jobs with that name, I know it's already setup, and I can skip the step of scheduling the job.</li>
</ul><h5>Running one-off jobs on deployment</h5><p>Something else I also like to do is run one-off tasks at deployment. Often these are related to recurring tasks, and I might want to fetch the content at initialization rather than waiting for the schedule. In other cases, I might want to do things like reset caches.</p><p>Because these scripts run <em>before</em> deployment, which might mean restarting the web server, or, more often, waiting for the php-fpm container and/or web server to be healthy, I cannot run the jobs <em>immediately</em>, because there's nothing to answer them.</p><p>The answer to this is to queue a job <em>in the future</em>:</p><pre class="language-php hljs php" data-lang="php">use DateTimeImmutable;
use ZendHQ\JobQueue\ScheduledTime;
$queue-&gt;scheduleJob($job, new ScheduledTime(new DateTimeImmutable('+1 minute')));
</pre><p>(I find it usually takes less than a minute for my FPM pool and/or web server to be online after running these scripts.)</p><p>The beauty of this approach is that my bootstrapping scripts now tend to be very fast, as I'm not trying to do all of this stuff before launching the site updates. The jobs then execute very soon after the site is up, and there's no noticeable differences in content or behavior.</p><h5>Closing notes</h5><p>I know I'm biased around ZendHQ. I'm also generally one of my own biggest critics. I had my team re-implement a lot of features that were present in Zend Server that I was never terribly keen on, and was hugely worried that we were going to make some of the same mistakes I felt we'd made with that product. However, the end result has been something that I am delighted to use, and which has opened up a ton of possibilities for how I build sites. The ability to warm my queues and manage them <em>just like the rest of my PHP application</em> is hugely powerful. I'm looking forward to seeing what others build with it!</p>]]></description>
      <link>https://mwop.net/blog/2024-05-07-zendhq-jq-warmup.html</link>
      <guid>https://mwop.net/blog/2024-05-07-zendhq-jq-warmup.html</guid>
      <pubDate>Tue, 07 May 2024 22:19:00 +0200</pubDate>
    </item>
    <item>
      <title><![CDATA[Local Whispers - Derick Rethans]]></title>
      <description><![CDATA[<p>For most of the <a href="https://www.youtube.com/@DerickRethansXdebug/videos">videos</a> that I make, I also like to have subtitles, because sometimes it's easier to just read along.</p><p>I used to make these subtitles with an online service called Otter.io, but they stopped allowing uploading of video files.</p><p>And then I found <a href="https://openai.com/index/whisper">Whisper</a>, which allows me to upload audio files to create subtitles. Whisper is an API from <a href="https://openai.com/">OpenAI</a>, mainly known for <a href="https://openai.com/chatgpt">ChatGPT</a>.</p><p>I didn't like having to upload everything to them either, as that means that they could train their model with my original video audio.</p><p>Whisper never really worked that well, because it broke up the sentences in weird places, and I had to make lots of edits. It look a long time to make subtitles.</p><p>I recently found out that it's actually possible to run Whisper locally, with an <a href="https://github.com/openai/whisper">open source project on GitHub</a>. I started looking into this to see whether I could use this to create subtitles instead.</p><p>The first thing that their <a href="https://github.com/openai/whisper?tab=readme-ov-file#setup">documentation</a> tells you to do is to run: <code>pip install openai-whisper</code>.</p><p>But I am on a Debian machine, and here Python is installed through distribution packages, and I don't really want to mess that up. <code>apt-get</code> actually suggests to create a virtual environment for Python.</p><p>In a virtual environment, you can install packages without affecting your system setup. Once you've made this virtual environment, there's actually Python binaries symlinked in there, that you can then use for installing things.</p><p>You create the virtual environment with:</p><pre>python3 -m venv `pwd`/whisper-local
cd whisper-local
</pre><p>In the <code>bin</code> directory you then have <code>python</code> and <code>pip</code>. That's the one you then use for installing packages.</p><p>Now let me run pip again, with the same options as before to install Whisper:</p><pre>bin/pip install -U openai-whisper
</pre><p>It takes quite some time to download. Once it is done, there is a new <code>whisper</code> binary in our <code>bin</code> directory.</p><p>You also need to install <code>fmpeg</code>:</p><pre>sudo apt-get install ffmpeg
</pre><p>Now we can run Whisper on a video I had made earlier:</p><pre>./bin/whisper ~/media/movie/xdebug33-from-exception.webm
</pre><p>The first time I ran this, I had some errors.</p><p>My video card does not have enough memory (2GB only). I don't actually have a very good video card at all, and was better off disabling it, by instructing "Torch" that I do not have one:</p><pre>export CUDA_VISIBLE_DEVICES=""
</pre><p>And then run Whisper again:</p><pre>./bin/whisper ~/media/movie/xdebug33-from-exception.webm
</pre><p>It first detects the language, which you can pre-empt by using <code>--language English</code>.</p><p>While it runs, it starts showing information in the console. I quickly noticed it was misspelling lots of things, such as my name Derick as Derek, and Xdebug as XDbook.</p><p>I also noticed that it starts breaking up sentences in a odd way after a while. Just like what the online version was doing.</p><p>I did not get a good result this first time.</p><p>It did create a JSON file, <code>xdebug33-from-exception.json</code>, but it is all in one line.</p><p>I reformatted it by installing the <code>yajl-tools</code> package with <code>apt-get</code>, and flowing the data through <code>json_reformat</code>:</p><pre>sudo apt-get install yajl-tools
cat xdebug33-from-exception.json | json_reformat &gt;xdebug33-from-exception_reformat.json
</pre><p>The reformatted file still has our full text in a line, but then a <code>segments</code> section follows, which looks like:</p><pre>"segments": [
    {
        "id": 0,
        "seek": 0,
        "start": 3.6400000000000006,
        "end": 11.8,
        "text": " Hi, I'm Derick. For most of the videos that I make, I also like to have subtitles, because",
        "tokens": [
                            50363, 15902, 11, 314, 1101, 9626, 624, 13, 1114, 749, 286,
                            262, 5861, 326, 314, 787, 11, 314, 635, 588, 284, 423, 44344,
                            11, 780, 50960
        ],
        "temperature": 0.0,
        "avg_logprob": -0.20771383965152435,
        "compression_ratio": 1.5128205128205128,
        "no_speech_prob": 0.31353551149368286,
            },
</pre><p>Each segment has an <code>id</code>, a <code>start</code> and <code>end</code> time (in seconds), the <code>text</code> for that segment, and a bunch of auxiliary information.</p><p>But it is still sort of a sentence at a time, which isn't really what we want. Additionally, I really don't want it to say XDbook and misspell my name.</p><p>For both of those there are actually options that we can use.</p><p>To make things easier for us later, we're turning on word timestamps. That allows us to by word see where the time index actually was. You do that with the <code>--word_timestamps True</code> option.</p><p>To provide a hint on what the video is about, and to get better words, we can use the initial prompt. The option that I used for this video was: <code>--initial_prompt="This video by Derick introduces a new Xdebug feature, regarding exceptions"</code>.</p><p>To make things more accurate or less accurate, there's also an option that you can specify which is which model to use. Normally the standard one medium is fine, but in order to speed up generation, you can use <code>--model tiny</code>. This will give less accurate results.</p><p>If the model has not been downloaded the before, Whisper will automatically do this.</p><p>It is also possible to specify the language, which makes things go faster if it's English only as well: <code>--language English</code>. It supports a bunch of languages.</p><p>The full command that I used is:</p><pre>CUDA_VISIBLE_DEVICES="" \
        ./bin/whisper ~/media/movie/xdebug33-from-exception.webm \
        --word_timestamps True \
        --initial_prompt="This video by Derick introduces a new Xdebug feature, regarding exceptions" \
        --language English
</pre><p>In the output file, we now see another elements in each sentence section:</p><pre>"words": [
    {
        "word": " Hi,",
        "start": 3.6400000000000006,
        "end": 4.16,
        "probability": 0.6476245522499084
    },
    {
        "word": " I'm",
        "start": 4.28,
        "end": 4.44,
        "probability": 0.9475358724594116
    },
    {
        "word": " Derick.",
        "start": 4.44,
        "end": 4.8,
        "probability": 0.12672505341470242
</pre><p>For each word, it has the <code>start</code> and <code>end</code>, as well as the probability of it being correct. You see that for <code>Derick</code> it was only 13% certain.</p><p>With this information you can do some analysis to create an actual subtitle script out of this. For that I have written a PHP <a href="https://gist.github.com/derickr/f30bc04c394e89573071171459f6a9d4">script</a>.</p><p>It loops over all the segments, and for each of the segments over all the words. If the difference in time between the end of a word and the start of a new word is more than a quarter of a second, it emits a new section of subtitles.</p><p>Similarly if a sentence is longer than 60 characters it also breaks it up into an extra line. This keeps all the subtitles reasonably well sorted.</p><p>The <code>emit</code> function formats it like how the SRT files are supposed to be.</p><p>With this script, I now create a new SRT file, overwriting the one that Whisper had created:</p><pre>php whisper-to-srt.php xdebug33-from-exception.json &gt; xdebug33-from-exception.rst
</pre><p>The output looks like:</p><pre>0
00:00:03,640 --&gt; 00:00:04,799
Hi, I'm Derick.
1
00:00:05,919 --&gt; 00:00:10,980
For most of the videos that I make, I also like to have subtitles,
2
00:00:11,640 --&gt; 00:00:15,779
because sometimes it's easier to just read along for various
different reasons.
</pre><p>These subtitles I can now add when uploading a video to YouTube. I might also create a similar script to generate output that can be used as the base for an textual article. Not everybody likes learning from watching videos.</p><p>I would also prefer not to use a model that has been trained with questionable sources. I will be investigating if I can use <a href="https://commonvoice.mozilla.org">Mozilla's Common Voice</a> project's data instead.</p>]]></description>
      <link>https://derickrethans.nl/local-whispers.html</link>
      <guid>https://derickrethans.nl/local-whispers.html</guid>
      <pubDate>Tue, 07 May 2024 16:15:00 +0200</pubDate>
    </item>
    <item>
      <title><![CDATA[Xdebug Update: April 2024 - Derick Rethans]]></title>
      <description><![CDATA[<p>I have not written an update like this for a while. I am sorry.</p><p>In the last months I have not spent a lot of time on Xdebug due to a set of other commitments.</p><p>Since my last update in November a few things have happened though.</p><div class="articleSubSection"><h2>Xdebug 3.3</h2><p>I released Xdebug 3.3, and the patch releases 3.3.1 and 3.3.2.</p><p><a href="https://xdebug.org/announcements/2023-11-30">Xdebug 3.3 brings</a> a bunch of new features into Xdebug, such as <a href="https://derickrethans.nl/flamboyant-flamegraphs.html">flamegraphs</a>.</p><p>The debugger has significant performance improvements in relation to breakpoints. And it can now also show the contents of ArrayIterator, SplDoublyLinkedList, SplPriorityQueue objects, and information about thrown exceptions.</p><p>A few bugs were present in 3.3.0, which have been addressed in 3.3.1 and 3.3.2. There is currently still an outstanding issue (or more than one), where Xdebug crashes. There are a lot of confusing reports about this, and I have not yet managed to reproduce any of them.</p><p>If you're running into a crash bug, please reach out to me.</p><p>There is also a new experimental feature: control sockets. These allow a client to instruct Xdebug to either initiate a debugging connection, or instigate a breakpoint out of band: i.e., when no debugging session is active. More about this in a later update.</p></div><div class="articleSubSection"><h2>Funding Platform</h2><p>Last year, I made a <a href="https://github.com/xdebug/xdebug/compare/master...derickr:xdebug:custom-map">prototype</a> as part of a talk that I gave at <a href="https://derickrethans.nl/talks/xdebug-neoscon23">NeosCon.io</a>. In this talk I demonstrated native path mapping — configuring path mapping in/through Xdebug, without an IDE's assistance.</p><p>In collaboration with Robert from <a href="https://www.neos.io/">NEOS</a>, and Luca from <a href="https://theaveragedev.com/">theAverageDev</a>, we defined a <a href="https://xdebug.org/funding/001-native-path-mapping">project plan</a> that explains all the necessary functionality and work.</p><p>Adding this to Xdebug is a huge effort, and therefore I decided to set up a way how projects like this could be funded.</p><p>There is now a dedicated <a href="https://xdebug.org/funding">Projects</a> section linked from the home page, with a list of all the projects. The page itself lists a short description for each project.</p><p>For each project, there is a full description and a list of its generous contributors. The <a href="https://xdebug.org/funding/001-native-path-mapping">Native Xdebug path Mapping</a> project is currently 85% funded. Once it is fully done, I will start the work to get this included in Xdebug 3.4. <a href="https://xdebug.org/support/buy/001-native-path-mapping">You could be part of this too</a>!</p></div><div class="articleSubSection"><h2>Xdebug Videos</h2><p>I have created several videos since November.</p><p>Two for <a href="https://www.youtube.com/playlist?list=PLg9Kjjye-m1g_eXpdaifUqLqALLqZqKd4">Xdebug</a>:</p><ul><li>
<p><a href="https://youtu.be/4EocpeKxI0k">Xdebug 3.3: Flamegraphs</a></p>
</li>
<li>
<p><a href="https://youtu.be/3FLdpMLBqMk">Xdebug 3.3: New Features in xdebug_get_function_stack()</a></p>
</li>
</ul><p>And several for writing PHP extensions, as part of a new <a href="https://www.youtube.com/playlist?list=PLg9Kjjye-m1hW4z0J-546qaFpysjlo27x">series</a>:</p><ul><li>
<p><a href="https://youtu.be/WjbKYHzoKM0">1. Writing PHP Extensions: Creating a Skeleton</a></p>
</li>
<li>
<p><a href="https://youtu.be/8N8Rk-BE0d4">2. Writing PHP Extensions: Importing the Library, and …</a></p>
</li>
<li>
<p><a href="https://youtu.be/-Tb_f55fc0k">3. Writing PHP Extensions: Implementing the rdp_simplify …</a></p>
</li>
</ul><p>If you have any suggestions, feel free to reach out to <a href="https://phpc.social/@derickr">me on Mastodon</a> or via <a href="http://derickrethans/who.html">email</a>.</p></div><div class="articleSubSection"><h2>Business Supporter Scheme and Funding</h2><p>In the last month, no new business supporters signed up.</p><p>Besides business support, I also maintain a <a href="https://www.patreon.com/derickr">Patreon</a> page, a profile on <a href="https://github.com/sponsors/derickr">GitHub sponsors</a>, as well as an <a href="https://opencollective.com/xdebug">OpenCollective</a> organisation.</p><p>If you want to contribute to specific projects, you can find those on the <a href="https://xdebug.org/funding">Projects</a> page.</p></div><div class="articleSubSection"><h2>Xdebug Cloud</h2><p>Xdebug Cloud is the <em>Proxy As A Service</em> platform to allow for debugging in more scenarios, where it is hard, or impossible, to have Xdebug make a connection to the IDE. It is continuing to operate as Beta release.</p><p>Packages start at £49/month, and I have recently introduced a package for larger companies. This has a larger initial set of tokens, and discounted extra tokens.</p><p>If you want to be kept up to date with Xdebug Cloud, please sign up to the <a href="https://xdebug.cloud/newsletter">mailinglist</a>, which I will use to send out an update not more than once a month.</p></div>]]></description>
      <link>https://derickrethans.nl/xdebug-update-april-2024.html</link>
      <guid>https://derickrethans.nl/xdebug-update-april-2024.html</guid>
      <pubDate>Mon, 06 May 2024 17:30:00 +0200</pubDate>
    </item>
    <item>
      <title><![CDATA[Xdebug Update: May 2024 - Derick Rethans]]></title>
      <description><![CDATA[<div class="article">
  <div class="body">
    <div class="articleListItem">
      <h1><a name="xdebug_update_may_2024"></a>Xdebug Update: May 2024</h1>
      <dl class="head"></dl><div class="articleMetaData">
        <div class="date">Monday, May 6th 2024, 16:30 BST</div>
        <div class="location"> London, UK</div>
      </div>
      <p>I have not written an update like this for a while. I am sorry.</p>
      <p>In the last months I have not spent a lot of time on Xdebug due to a set of other commitments.</p>
      <p>Since my last update in November a few things have happened though.</p>
      <div class="articleSubSection">
        <h2><a name="xdebug_3_3"></a>Xdebug 3.3</h2>
        <p>I released Xdebug 3.3, and the patch releases 3.3.1 and 3.3.2.</p>
        <p><a href="https://xdebug.org/announcements/2023-11-30">Xdebug 3.3 brings</a> a bunch of new features into Xdebug, such as <a href="https://derickrethans.nl/flamboyant-flamegraphs.html">flamegraphs</a>.</p>
        <p>The debugger has significant performance improvements in relation to breakpoints. And it can now also show the contents of ArrayIterator, SplDoublyLinkedList, SplPriorityQueue objects, and information about thrown exceptions.</p>
        <p>A few bugs were present in 3.3.0, which have been addressed in 3.3.1 and 3.3.2. There is currently still an outstanding issue (or more than one), where Xdebug crashes. There are a lot of confusing reports about this, and I have not yet managed to reproduce any of them.</p>
        <p>If you're running into a crash bug, please reach out to me.</p>
        <p>There is also a new experimental feature: control sockets. These allow a client to instruct Xdebug to either initiate a debugging connection, or instigate a breakpoint out of band: i.e., when no debugging session is active. More about this in a later update.</p>
      </div>
      <div class="articleSubSection">
        <h2><a name="funding_platform"></a>Funding Platform</h2>
        <p>Last year, I made a <a href="https://github.com/xdebug/xdebug/compare/master...derickr:xdebug:custom-map">prototype</a> as part of a talk that I gave at <a href="https://derickrethans.nl/talks/xdebug-neoscon23">NeosCon.io</a>. In this talk I demonstrated native path mapping — configuring path mapping in/through Xdebug, without an IDE's assistance.</p>
        <p>In collaboration with Robert from <a href="https://www.neos.io/">NEOS</a>, and Luca from <a href="https://theaveragedev.com/">theAverageDev</a>, we defined a <a href="https://xdebug.org/funding/001-native-path-mapping">project plan</a> that explains all the necessary functionality and work.</p>
        <p>Adding this to Xdebug is a huge effort, and therefore I decided to set up a way how projects like this could be funded.</p>
        <p>There is now a dedicated <a href="https://xdebug.org/funding">Projects</a> section linked from the home page, with a list of all the projects. The page itself lists a short description for each project.</p>
        <p>For each project, there is a full description and a list of its generous contributors. The <a href="https://xdebug.org/funding/001-native-path-mapping">Native Xdebug path Mapping</a> project is currently 85% funded. Once it is fully done, I will start the work to get this included in Xdebug 3.4. <a href="https://xdebug.org/support/buy/001-native-path-mapping">You could be part of this too</a>!</p>
      </div>
      <div class="articleSubSection">
        <h2><a name="xdebug_videos"></a>Xdebug Videos</h2>
        <p>I have created several videos since November.</p>
        <p>Two for <a href="https://www.youtube.com/playlist?list=PLg9Kjjye-m1g_eXpdaifUqLqALLqZqKd4">Xdebug</a>:</p>
        <ul><li>
            <p>
              <a href="https://youtu.be/4EocpeKxI0k">Xdebug 3.3: Flamegraphs</a>
            </p>
          </li>
          <li>
            <p>
              <a href="https://youtu.be/3FLdpMLBqMk">Xdebug 3.3: New Features in xdebug_get_function_stack()</a>
            </p>
          </li>
        </ul><p>And several for writing PHP extensions, as part of a new <a href="https://www.youtube.com/playlist?list=PLg9Kjjye-m1hW4z0J-546qaFpysjlo27x">series</a>:</p>
        <ul><li>
            <p>
              <a href="https://youtu.be/WjbKYHzoKM0">1. Writing PHP Extensions: Creating a Skeleton</a>
            </p>
          </li>
          <li>
            <p>
              <a href="https://youtu.be/8N8Rk-BE0d4">2. Writing PHP Extensions: Importing the Library, and …</a>
            </p>
          </li>
          <li>
            <p>
              <a href="https://youtu.be/-Tb_f55fc0k">3. Writing PHP Extensions: Implementing the rdp_simplify …</a>
            </p>
          </li>
        </ul><p>If you have any suggestions, feel free to reach out to <a href="https://phpc.social/@derickr">me on Mastodon</a> or via <a href="http://derickrethans/who.html">email</a>.</p>
      </div>
      <div class="&lt;/body"></div></div></div></div><p><i>Truncated by Planet PHP, read more at <a href="https://derickrethans.nl/xdebug-update-may-2024.html">the original</a> (another 1644 bytes)</i></p>]]></description>
      <link>https://derickrethans.nl/xdebug-update-may-2024.html</link>
      <guid>https://derickrethans.nl/xdebug-update-may-2024.html</guid>
      <pubDate>Mon, 06 May 2024 17:30:00 +0200</pubDate>
    </item>
    <item>
      <title><![CDATA[python-oracledb 2.2 and the VECTOR type in Oracle Database 23ai - Christopher Jones]]></title>
      <description><![CDATA[<div><div class="hu hv hw hx hy"></div><p id="8a89" class="pw-post-body-paragraph mk ml gt mm b mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne nf ng nh gm bj"><a class="af ni" href="https://oracle.github.io/python-oracledb/index.html" rel="noopener ugc nofollow" target="_blank"><strong class="mm gu">python-oracledb 2.2</strong></a><strong class="mm gu">, the extremely popular Oracle Database interface for Python, is now on </strong><a class="af ni" href="https://pypi.python.org/pypi/oracledb/" rel="noopener ugc nofollow" target="_blank"><strong class="mm gu">PyPI</strong></a><strong class="mm gu">.</strong></p><p id="f442" class="pw-post-body-paragraph mk ml gt mm b mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne nf ng nh gm bj">Today we’re pleased to release python-oracledb 2.2 to coincide with the just-announced, <a class="af ni" href="https://blogs.oracle.com/database/post/oracle-23ai-now-generally-available" rel="noopener ugc nofollow" target="_blank">general availability of Oracle Database 23ai</a>.</p><figure class="nm nn no np nq nr nj nk paragraph-image"><div role="button" tabindex="0" class="ns nt fi nu bg nv"><div class="nj nk nl"><picture><source srcset="https://miro.medium.com/v2/resize:fit:640/format:webp/0*-JQymjaXpztX4o5_ 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/0*-JQymjaXpztX4o5_ 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/0*-JQymjaXpztX4o5_ 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/0*-JQymjaXpztX4o5_ 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/0*-JQymjaXpztX4o5_ 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/0*-JQymjaXpztX4o5_ 1100w, https://miro.medium.com/v2/resize:fit:1400/format:webp/0*-JQymjaXpztX4o5_ 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" type="image/webp" /><source data-testid="og" srcset="https://miro.medium.com/v2/resize:fit:640/0*-JQymjaXpztX4o5_ 640w, https://miro.medium.com/v2/resize:fit:720/0*-JQymjaXpztX4o5_ 720w, https://miro.medium.com/v2/resize:fit:750/0*-JQymjaXpztX4o5_ 750w, https://miro.medium.com/v2/resize:fit:786/0*-JQymjaXpztX4o5_ 786w, https://miro.medium.com/v2/resize:fit:828/0*-JQymjaXpztX4o5_ 828w, https://miro.medium.com/v2/resize:fit:1100/0*-JQymjaXpztX4o5_ 1100w, https://miro.medium.com/v2/resize:fit:1400/0*-JQymjaXpztX4o5_ 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" /></picture></div></div><figcaption class="nx fe ny nj nk nz oa be b bf z dt">Photo by <a class="af ni" href="https://unsplash.com/@jamie452?utm_source=medium&amp;utm_medium=referral" rel="noopener ugc nofollow" target="_blank">Jamie Street</a> on <a class="af ni" href="https://unsplash.com/?utm_source=medium&amp;utm_medium=referral" rel="noopener ugc nofollow" target="_blank">Unsplash</a></figcaption></figure><p id="8564" class="pw-post-body-paragraph mk ml gt mm b mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne nf ng nh gm bj">Python-oracledb is an open source package for the Python Database API specification with many additions to support advanced Oracle Database features. It is the new name for the cx_Oracle driver.</p><h1 id="f9c7" class="ob oc gt be od oe of og oh oi oj ok ol om on oo op oq or os ot ou ov ow ox oy bj">Main Changes for Oracle Database 23ai</h1><h2 id="4894" class="oz oc gt be od pa pb dx oh pc pd dz ol mv pe pf pg mz ph pi pj nd pk pl pm pn bj"><strong class="al">Support for the Oracle Database 23ai </strong><a class="af ni" href="https://docs.oracle.com/en/database/oracle/oracle-database/23/vecse/create-tables-using-vector-data-type.html" rel="noopener ugc nofollow" target="_blank"><strong class="al">VECTOR</strong></a><strong class="al"> data type</strong></h2><p id="fb21" class="pw-post-body-paragraph mk ml gt mm b mn po mp mq mr pp mt mu mv pq mx my mz pr nb nc nd ps nf ng nh gm bj">A major feature of Oracle Database 23ai is <a class="af ni" href="https://docs.oracle.com/en/database/oracle/oracle-database/23/nfcoa/ai_vector_search.html#GUID-aivecsearch-general1" rel="noopener ugc nofollow" target="_blank">AI Vector Search</a> (which is part of the database and is available at no additional charge in Enterprise Edition, Standard Edition 2, Database Free, and all Oracle Database cloud services).</p><p id="f8c4" class="pw-post-body-paragraph mk ml gt mm b mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne nf ng nh gm bj">Python-oracle supports this feature with its native capabilities for binding and fetching the new VECTOR data type. For example, given the table:</p><pre class="nm nn no np nq pt pu pv bo pw ba bj">SQL&gt; drop table if exists mytab_v; <br />SQL&gt; create table mytab_v (v64 vector(3, float64));</pre><p id="2a07" class="pw-post-body-paragraph mk ml gt mm b mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne nf ng nh gm bj">Python code to insert a vector could look like:</p><pre class="nm nn no np nq pt pu pv bo pw ba bj">vector_data_64 = array.array("d", [11.25, 11.75, 11.5])cursor.execute(<br />    "insert into mytab_v (v64) values (:1)",<br />    [vector_data_64]<br />)</pre><p id="d51e" class="pw-post-body-paragraph mk ml gt mm b mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne nf ng nh gm bj">A query:</p><pre class="nm nn no np nq pt pu pv bo pw ba bj">cursor.execute("select * from mytab_v")<br />for row in cursor:<br />    print(row)</pre><p id="4f9f" class="pw-post-body-paragraph mk ml gt mm b mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne nf ng nh gm bj">would then show:</p><pre class="nm nn no np nq pt pu pv bo pw ba bj">(array('d', [11.25, 11.75, 11.5]),)</pre><p id="4037" class="pw-post-body-paragraph mk ml gt mm b mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne nf ng nh gm bj">Other examples are on <a class="af ni" href="https://github.com/oracle/python-oracledb/tree/main/samples" rel="noopener ugc nofollow" target="_blank">GitHub</a>.</p><p id="44d0" class="pw-post-body-paragraph mk ml gt mm b mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne nf ng nh gm bj">(And did you note the new <code class="cw qc qd qe pu b">DROP TABLE IF EXISTS</code> syntax I used?!</p><h2 id="83a8" class="oz oc gt be od pa pb dx oh pc pd dz ol mv pe pf pg mz ph pi pj nd pk pl pm pn bj"><strong class="al">Support for the Oracle Database 23ai BOOLEAN data type</strong></h2><p id="a19b" class="pw-post-body-paragraph mk ml gt mm b mn po mp mq mr pp mt mu mv pq mx my mz pr nb nc nd ps nf ng nh gm bj">Oracle Database 23ai’s new SQL <a class="af ni" href="https://docs.oracle.com/en/database/oracle/oracle-database/23/sqlrf/Data-Types.html#GUID-285FFCA8-390D-4FA9-9A51-47B84EF5F83A" rel="noopener ugc nofollow" target="_blank">BOOLEAN</a> data type lets you store <em class="qf">true</em> and <em class="qf">false</em> values in database tables. (Previously this type was only available in PL/SQL).</p><p id="28e2" class="pw-post-body-paragraph mk ml gt mm b mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne nf ng nh gm bj">Python-oracledb 2.2 supports binding and fetching SQL BOOLEAN values. For example:</p><pre class="nm nn no np nq pt pu pv bo pw ba bj">bv = cursor.var(oracledb.DB_TYPE_BOOLEAN)<br />bv.setvalue(0, True)<br />for r, in cursor.execute("select :bv", [bv]):<br />    print(r)</pre><p id="4d1a" class="pw-post-body-paragraph mk ml gt mm b mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne nf ng nh gm bj">displays:</p><pre class="nm nn no np nq pt pu pv bo pw ba bj">True</pre><p id="414f" class="pw-post-body-paragraph mk ml gt mm b mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne nf ng nh gm bj">Note there is no <code class="cw qc qd qe pu b">FROM DUAL</code> in the query! One Oracle Database 23ai enhancement was to make the clause optional in this common query idiom.</p><h2 id="9358" class="oz oc gt be od pa pb dx oh pc pd dz ol mv pe pf pg mz ph pi pj nd pk pl pm pn bj"><strong class="al">Support for the Oracle Database INTERVAL YEAR TO MONTH data type</strong></h2><p id="9153" class="pw-post-body-paragraph mk ml gt mm b mn po mp mq mr pp mt mu mv pq mx my mz pr nb nc nd ps nf ng nh gm bj">The not-so-common <a class="af ni" href="https://docs.oracle.com/en/database/oracle/oracle-database/23/sqlrf/Literals.html#GUID-4C258D8F-3DF2-4D45-BE3E-14864DD77100" rel="noopener ugc nofollow" target="_blank">INTERVAL YEAR TO MONTH</a> data type is not new to the database, but python-oracledb 2.2 now has support via an<code class="cw qc qd qe pu b">oracledb.IntervalYM</code> class. The class is a named tuple with two integer attributes, <code class="cw qc qd qe pu b">years</code> and <code class="cw qc qd qe pu b">months</code>. The code:</p><pre class="nm nn no np nq pt pu pv bo pw ba bj">bv = cursor.var(oracledb.DB_TYPE_INTERVAL_YM)<br />bv.setvalue(0, oracledb.IntervalYM(years=3, months=10))<br />cursor.execute("insert into mytab_b (iym_col) values (:1)", [bv])for r, in cursor.execute("select * from mytab_b"):<br />    print(r)</pre><p id="d356" class="pw-post-body-paragraph mk ml gt mm b mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne nf ng nh gm bj">displays:</p><pre class="nm nn no np nq pt pu pv bo pw ba bj">IntervalYM(years=3, months=10)</pre><h2 id="c771" class="oz oc gt be od pa pb dx oh pc pd dz ol mv pe pf pg mz ph pi pj nd pk pl pm pn bj"><strong class="al">Oracle Database 23ai JSON and SODA improvements</strong></h2><p id="6ac3" class="pw-post-body-paragraph mk ml gt mm b mn po mp mq mr pp mt mu mv pq mx my mz pr nb nc nd ps nf ng nh gm bj">One big Oracle Database 23ai announcement is <a class="af ni" href="https://docs.oracle.com/en/database/oracle/oracle-database/23/jsnvu/overview-json-relational-duality-views.html" rel="noopener ugc nofollow" target="_blank">JSON Relational Duality</a>, letting you leverage the power of relational and the simplicity of JSON development within a single app. Also check out <a class="af ni" href="https://blogs.oracle.com/database/post/json-relational-duality-app-dev" rel="noopener ugc nofollow" target="_blank">this blog post</a>.</p><p id="6980" class="pw-post-body-paragraph mk ml gt mm b mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne nf ng nh gm bj">Various enhancements to python-oracledb improve its support for <a class="af ni" href="https://python-oracledb.readthedocs.io/en/latest/user_guide/json_data_type.html" rel="noopener ugc nofollow" target="_blank">JSON</a> and <a class="af ni" href="https://python-oracledb.readthedocs.io/en/latest/user_guide/soda.html" rel="noopener ugc nofollow" target="_blank">SODA</a> features in Oracle Database 23ai.</p><h2 id="92fc" class="oz oc gt be od pa pb dx oh pc pd dz ol mv pe pf pg mz ph pi pj nd pk pl pm pn bj"><strong class="al">Oracle Database 23ai Implicit Connection Pooling</strong></h2><p id="5705" class="pw-post-body-paragraph mk ml gt mm b mn po mp mq mr pp mt mu mv pq mx my mz pr nb nc nd ps nf ng nh gm bj">Implicit connection pooling is a great feature that leverages Oracle Database’s popular <a class="af ni" href="https://python-oracledb.readthedocs.io/en/latest/user_guide/connection_handling.html#database-resident-connection-pooling-drcp" rel="noopener ugc nofollow" target="_blank">DRCP</a> pooling. The intended use case is for applications that are <strong class="mm gu">not</strong> using python-oracledb connection pooling, but have become popular and are now causing excess connection load on the database server. Typically legacy applications can’t be modified to explicitly use application connection pooling calls. However they can make use of implicit connection pooling simply by starting DRCP in the database and then using a new connection string option <code class="cw qc qd qe pu b">POOL_BOUNDARY</code>. The driver then automatically associates and disassociates DRCP pooled servers from application connections as they are actually used by the application to do database work. This can occur transparently between the application's explicit <code class="cw qc qd qe pu b">oracledb.connect()</code> call and the <code class="cw qc qd qe pu b">connection.close()</code> (or equivalent application's connection release at end-of-scope). By allowing each database pooled server to be used by multiple application connections, the load on the database host is reduced.</p><p id="c27a" class="pw-post-body-paragraph mk ml gt mm b mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne nf ng nh gm bj">Implicit connection pooling is available in both python-oracledb Thin and <a class="af ni" href="https://python-oracledb.readthedocs.io/en/latest/user_guide/initialization.html#enabling-python-oracledb-thick-mode" rel="noopener ugc nofollow" target="_blank">Thick</a> modes. It works with DRCP and also with CMAN-TDM’s <a class="af ni" href="https://download.oracle.com/%0Aocomdocs/global/CMAN_TDM_Oracle_DB_Connection_Proxy_for_scalable_apps.pdf" rel="noopener ugc nofollow" target="_blank">Proxy Connection Pooling</a> (PRCP). CMAN-TDM is Oracle Database’s mid-tier proxy solution.</p><p id="c7bb" class="pw-post-body-paragraph mk ml gt mm b mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne nf ng nh gm bj">As an example, to use implicit connection pooling with DRCP, your python-oracledb connection string might look like:</p><pre class="nm nn no np nq pt pu pv bo pw ba bj">dsn = "localhost:1521/orclpdb:pooled?pool_boundary=statement"</pre><h2 id="6a3b" class="oz oc gt be od pa pb dx oh pc pd dz ol mv pe pf pg mz ph pi pj nd pk pl pm pn bj"><strong class="al">Oracle Database 23ai Improved Connections</strong></h2><p id="3476" class="pw-post-body-paragraph mk ml gt mm b mn po mp mq mr pp mt mu mv pq mx my mz pr nb nc nd ps nf ng nh gm bj">During the Oracle Database 23ai development cycle there were improvements to the database stack, and also in the Oracle Cloud networking infrastructure, that help connection performance in various scenarios. Some changes reduce the time to connect to the database, while others improve the transport across established connections. Oracle Database’s language drivers benefit in different ways. I can’t point to a specific “tell all” benchmark because there are lots of different connection configurations (such as the speed of your network, whether dedicated or pre-spawned server process are being used, whether encryption is being used, what language stack is used, are you in the cloud etc., etc.) but overall we’re very happy with the improvements.</p><p id="3afb" class="pw-post-body-paragraph mk ml gt mm b mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne nf ng nh gm bj">Some of the specific changes in the python-oracledb driver include:</p><ul class=""><li id="a281" class="mk ml gt mm b mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne nf ng nh qg qh qi bj">Internal optimization in Python-oracledb Thin mode (and Thick mode when using Oracle Client 23ai libraries) to reduce overheads and connection establishment times when connecting to Oracle Database 23ai.</li><li id="9180" class="mk ml gt mm b mn qj mp mq mr qk mt mu mv ql mx my mz qm nb nc nd qn nf ng nh qg qh qi bj">Internal support for an Oracle Database 23ai network protocol improvement that directly benefits python-oracledb’s <a class="af ni" href="https://python-oracledb.readthedocs.io/en/latest/user_guide/asyncio.html" rel="noopener ugc nofollow" target="_blank">asyncio</a> (and <a class="af ni" href="https://oracle.github.io/node-oracledb/" rel="noopener ugc nofollow" target="_blank">node-oracledb’s</a>) performance when fetching large columns. This lets python-oracledb 2.2 more efficiently handle internal packet management.</li></ul><h2 id="7d94" class="oz oc gt be od pa pb dx oh pc pd dz ol mv pe pf pg mz ph pi pj nd pk pl pm pn bj"><strong class="al">Oracle Database 23ai SQL Annotations</strong></h2><p id="c9d1" class="pw-post-body-paragraph mk ml gt mm b mn po mp mq mr pp mt mu mv pq mx my mz pr nb nc nd ps nf ng nh gm bj">The python-oracledb query metadata attribute <a class="af ni" href="https://python-oracledb.readthedocs.io/en/latest/api_manual/fetch_info.html#FetchInfo.annotations" rel="noopener ugc nofollow" target="_blank">FetchInfo.annotation</a> returns a dictionary containing the database <a class="af ni" href="https://docs.oracle.com/en/database/oracle/oracle-database/23/sqlrf/annotations_clause.html" rel="noopener ugc nofollow" target="_blank">annotations</a> associated with a fetched column. Annotations provide a mechanism to store application metadata centrally in the database so that they can be shared across applications, modules and microservices.</p><h2 id="6692" class="oz oc gt be od pa pb dx oh pc pd dz ol mv pe pf pg mz ph pi pj nd pk pl pm pn bj"><strong class="al">Oracle Database 23ai SQL Domains</strong></h2><p id="376b" class="pw-post-body-paragraph mk ml gt mm b mn po mp mq mr pp mt mu mv pq mx my mz pr nb nc nd ps nf ng nh gm bj">The python-oracledb query metadata attributes <a class="af ni" href="https://python-oracledb.readthedocs.io/en/latest/api_manual/fetch_info.html#FetchInfo.domain_schema" rel="noopener ugc nofollow" target="_blank">FetchInfo.domain_schema</a> and <a class="af ni" href="https://python-oracledb.readthedocs.io/en/latest/api_manual/fetch_info.html#FetchInfo.domain_name" rel="noopener ugc nofollow" target="_blank">FetchInfo.domain_name</a> support <a class="af ni" href="https://docs.oracle.com/en/database/oracle/oracle-database/23/sqlrf/create-domain.html" rel="noopener ugc nofollow" target="_blank">data use case domain information</a> associated with a fetched column.</p><p id="0e2a" class="pw-post-body-paragraph mk ml gt mm b mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne nf ng nh gm bj">A use case domain is high-level dictionary object that belongs to a schema and encapsulates a set of optional properties and constraints. You can define table columns to be associated with a domain, thereby explicitly applying the domain’s optional properties and constraints to the columns.</p><h2 id="9098" class="oz oc gt be od pa pb dx oh pc pd dz ol mv pe pf pg mz ph pi pj nd pk pl pm pn bj"><strong class="al">Oracle Database Error URLs</strong></h2><p id="8a50" class="pw-post-body-paragraph mk ml gt mm b mn po mp mq mr pp mt mu mv pq mx my mz pr nb nc nd ps nf ng nh gm bj">One recent database group project was a review and rewording of common database error messages. An <a class="af ni" href="https://docs.oracle.com/en/error-help/db/index.html" rel="noopener ugc nofollow" target="_blank">error portal</a> now contains database messages with their Cause and Action help information. Python-oracledb will show a link to the relevant portal entry when printing database error messages. By following the link, further troubleshooting information is available to you. For example:</p><pre class="nm nn no np nq pt pu pv bo pw ba bj">$ python t.py ORA-01017: invalid credential or not authorized; logon denied <br />Help: https://docs.oracle.com/error-help/db/ora-01017/</pre><p id="4efc" class="pw-post-body-paragraph mk ml gt mm b mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne nf ng nh gm bj">These help links are displayed in Thin and Thick modes. With Thick mode, Oracle Client 23ai libraries are needed.</p><h1 id="f1fe" class="ob oc gt be od oe of og oh oi oj ok ol om on oo op oq or os ot ou ov ow ox oy bj">Summary</h1><p id="81e9" class="pw-post-body-paragraph mk ml gt mm b mn po mp mq mr pp mt mu mv pq mx my mz pr nb nc nd ps nf ng nh gm bj">See the python-oracledb <a class="af ni" href="https://python-oracledb.readthedocs.io/en/latest/release_notes.html" rel="noopener ugc nofollow" target="_blank">Release Notes</a> for more improvements and bug fixes. Some recent versions had limited support for pre-release Oracle Database 23ai and the Oracle Database 23.3 Free edition features, but we <strong class="mm gu">strongly</strong> <strong class="mm gu">encourage</strong> you to upgrade to python-oracledb 2.2 if you are using any edition of Oracle Database 23.4 because of recent internal changes.</p><p id="5717" class="pw-post-body-paragraph mk ml gt mm b mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne nf ng nh gm bj">Don’t forget there are many great Oracle Database 23ai features that are part of the database itself, or are usable through SQL and PL/SQL — or are in other tools. See the <a class="af ni" href="https://docs.oracle.com/en/database/oracle/oracle-database/23/nfcoa/" rel="noopener ugc nofollow" target="_blank">Oracle Database New Features</a> guide.</p><p id="20a0" class="pw-post-body-paragraph mk ml gt mm b mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne nf ng nh gm bj">For examples, did you know SQL*Plus 23ai has a <a class="af ni" href="https://docs.oracle.com/en/database/oracle/oracle-database/23/sqpug/ping.html#GUID-60C4A1C5-535A-4C9B-88F7-DDE2C198FD6E" rel="noopener ugc nofollow" target="_blank">new </a><code class="cw qc qd qe pu b"><a class="af ni" href="https://docs.oracle.com/en/database/oracle/oracle-database/23/sqpug/ping.html#GUID-60C4A1C5-535A-4C9B-88F7-DDE2C198FD6E" rel="noopener ugc nofollow" target="_blank">PING</a></code><a class="af ni" href="https://docs.oracle.com/en/database/oracle/oracle-database/23/sqpug/ping.html#GUID-60C4A1C5-535A-4C9B-88F7-DDE2C198FD6E" rel="noopener ugc nofollow" target="_blank"> command</a> and a matching command line <code class="cw qc qd qe pu b">-P</code> option to ping the database? This removes the need to install <code class="cw qc qd qe pu b">tnsping</code> to check database availability. Did you know that you can use <a class="af ni" href="https://docs.oracle.com/en/database/oracle/oracle-database/23/mlejs/mle-js-modules-and-environments.html#GUID-FEF2CACF-9659-4D5A-9D6B-D2E66E8961F4" rel="noopener ugc nofollow" target="_blank">JavaScript for Oracle Database stored procedures</a>? Did you know that our C language Oracle Call Interface API now supports database <a class="af ni" href="https://medium.com/@veronica.dumitriu/introducing-pipelining-and-asynch-programming-for-oracle-database-23c-2ec67fa7d2af" rel="noopener">request pipelining</a>? Database pipelining is something we'd like to expose in a future python-oracle version, so stay tuned to our release announcements!</p><p id="b751" class="pw-post-body-paragraph mk ml gt mm b mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne nf ng nh gm bj">Finally, if you are taking advantage of Oracle Database 23ai Free in Oracle Cloud, then our documentation <a class="af ni" href="https://python-oracledb.readthedocs.io/en/latest/user_guide/connection_handling.html#connecting-to-oracle-cloud-autonomous-databases" rel="noopener ugc nofollow" target="_blank">Connecting to Oracle Cloud Autonomous Databases</a> will be useful.</p><h1 id="2594" class="ob oc gt be od oe of og oh oi oj ok ol om on oo op oq or os ot ou ov ow ox oy bj">Installing or Upgrading python-oracledb</h1><p id="cc6d" class="pw-post-body-paragraph mk ml gt mm b mn po mp mq mr pp mt mu mv pq mx my mz pr nb nc nd ps nf ng nh gm bj">You can install or upgrade python-oracledb by running:</p><pre class="nm nn no np nq pt pu pv bo pw ba bj">python -m pip install oracledb --upgrade</pre><p id="af6e" class="pw-post-body-paragraph mk ml gt mm b mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne nf ng nh gm bj">The <code class="cw qc qd qe pu b">pip</code> options <code class="cw qc qd qe pu b">--proxy</code> and <code class="cw qc qd qe pu b">--user</code> may be useful in some environments. See <a class="af ni" href="https://python-oracledb.readthedocs.io/en/latest/user_guide/installation.html" rel="noopener ugc nofollow" target="_blank">python-oracledb Installation</a> for details.</p><h1 id="7a5f" class="ob oc gt be od oe of og oh oi oj ok ol om on oo op oq or os ot ou ov ow ox oy bj">Python-oracledb References</h1><p id="3d5a" class="pw-post-body-paragraph mk ml gt mm b mn po mp mq mr pp mt mu mv pq mx my mz pr nb nc nd ps nf ng nh gm bj">Home page: <a class="af ni" href="https://oracle.github.io/python-oracledb/index.html" rel="noopener ugc nofollow" target="_blank">oracle.github.io/python-oracledb/index.html</a></p><p id="881a" class="pw-post-body-paragraph mk ml gt mm b mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne nf ng nh gm bj">Installation instructions: <a class="af ni" href="https://python-oracledb.readthedocs.io/en/latest/user_guide/installation.html" rel="noopener ugc nofollow" target="_blank">python-oracledb.readthedocs.io/en/latest/installation.html</a></p><p id="a7b8" class="pw-post-body-paragraph mk ml gt mm b mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne nf ng nh gm bj">Documentation: <a class="af ni" href="https://python-oracledb.readthedocs.io/en/latest/index.html" rel="noopener ugc nofollow" target="_blank">python-oracledb.readthedocs.io/en/latest/index.html</a></p><p id="7a53" class="pw-post-body-paragraph mk ml gt mm b mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne nf ng nh gm bj">Release Notes: <a class="af ni" href="https://python-oracledb.readthedocs.io/en/latest/release_notes.html" rel="noopener ugc nofollow" target="_blank">python-oracledb.readthedocs.io/en/latest/release_notes.html</a></p><p id="66fd" class="pw-post-body-paragraph mk ml gt mm b mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne nf ng nh gm bj">Discussions: <a class="af ni" href="https://github.com/oracle/python-oracledb/discussions" rel="noopener ugc nofollow" target="_blank">github.com/oracle/python-oracledb/discussions</a></p><p id="2d1c" class="pw-post-body-paragraph mk ml gt mm b mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne nf ng nh gm bj">Issues: <a class="af ni" href="https://github.com/oracle/python-oracledb/issues" rel="noopener ugc nofollow" target="_blank">github.com/oracle/python-oracledb/issues</a></p><p id="0e4c" class="pw-post-body-paragraph mk ml gt mm b mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne nf ng nh gm bj">Source Code Repository: <a class="af ni" href="https://github.com/oracle/python-oracledb" rel="noopener ugc nofollow" target="_blank">github.com/oracle/python-oracledb</a></p></div>]]></description>
      <link>https://medium.com/oracledevs/python-oracledb-2-2-and-the-vector-type-in-oracle-database-23ai-7eb258a2ea3f?source=rss-adc937c3a9d------2</link>
      <guid>https://medium.com/oracledevs/python-oracledb-2-2-and-the-vector-type-in-oracle-database-23ai-7eb258a2ea3f?source=rss-adc937c3a9d------2</guid>
      <pubDate>Sat, 04 May 2024 08:38:00 +0200</pubDate>
    </item>
    <item>
      <title><![CDATA[Statement on glibc/iconv Vulnerability - PHP: Hypertext Preprocessor]]></title>
      <description><![CDATA[<div><header class="title"><time datetime="2024-04-24T18:40:29+00:00">24 Apr 2024</time>
</header><div class="newscontent"><p>Recently, a bug in <strong>glibc</strong> version 2.39 and older (<a href="https://www.php.net/archive/entries/2024-04-24-1.xml">CVE-2024-2961</a>) was uncovered where a buffer overflow in character set conversions *to* the ISO-2022-CN-EXT character set.</p><p>This specific buffer overflow in glibc is exploitable through PHP, which uses the iconv functionality in glibc to do character set conversions. Although the bug is exploitable in the context of the PHP Engine, the bug is not in PHP. It is also not directly exploitable remotely.</p><p>There are numerous reports online with titles like "Mitigating the iconv Vulnerability for PHP (CVE-2024-2961)" or "PHP Under Attack". These titles are misleading as this is *not* a bug in PHP itself.</p><p>Currently there is no fix for this issue, but there is a workaround described in <a href="https://rockylinux.org/news/glibc-vulnerability-april-2024/">GLIBC Vulnerability on Servers Serving PHP</a>. It explains a way how to remove the problematic character set from glibc. Perform this procedure for every gconv-modules-extra.conf file that is available on your system.</p><p>Additionally it is also good practice for applications to accept only specific charsets, with an allow-list.</p><p>Some Linux distributions such as <a href="https://www.php.net/GLIBC%20Vulnerability%20on%20Servers%20Serving%20PHP">Debian</a>, CentOS, and others, already have published patched variants of glibc. Please upgrade as soon as possible.</p><p>Once an update is available in glibc, updating that package on your Linux machine will be enough to alleviate the issue. You do not need to update PHP, as glibc is a dynamically linked library.</p><p>PHP users on Windows are not affected.</p><p>There will therefore also not be a new version of PHP for this vulnerability.</p></div></div><div><header class="title"><time datetime="2024-04-12T15:42:40+00:00">12 Apr 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.1.28. This is a security release.</p><p>All PHP 8.1 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.1.28 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.1.28">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-04-11T14:34:04+00:00">11 Apr 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.3.6. This is a security release.</p><p>All PHP 8.3 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.3.6 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.3.6">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-04-11T13:37:51+00:00">11 Apr 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.18. This is a security release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.18 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.18">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-03-14T21:02:45+00:00">14 Mar 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.3.4. This is a bug fix release.</p><p>All PHP 8.3 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.3.4 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.3.4">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-03-14T15:21:29+00:00">14 Mar 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.17. This is a bug fix release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.17 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.17">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-02-15T13:36:20-05:00">15 Feb 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.16. This is a bug fix release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.16 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.16">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-02-15T15:48:46+00:00">15 Feb 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.3.3. This is a bug fix release.</p><p>All PHP 8.3 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.3.3 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.3.3">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-01-18T15:35:45+00:00">18 Jan 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.15. This is a bug fix release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.15 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.15">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2024-01-18T14:47:41+00:00">18 Jan 2024</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.3.2. This is a bug fix release.</p><p>All PHP 8.3 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.3.2 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.3.2">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2023-12-21T14:28:29-05:00">21 Dec 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.14. This is a bug fix release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.14 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.14">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2023-12-21T16:12:41+00:00">21 Dec 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.1.27. This is a bug fix release.</p><p>All PHP 8.1 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.1.27 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.1.27">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2023-12-21T07:48:56-08:00">21 Dec 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.3.1. This is a bug fix release.</p><p>All PHP 8.3 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.3.1 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.3.1">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2023-11-23T18:24:51+00:00">23 Nov 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.1.26. This is a bug fix release.</p><p>All PHP 8.1 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.1.26 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.1.26">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2023-11-23T15:43:03+00:00">23 Nov 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.3.0. This release marks the latest minor release of the PHP language.</p><p>PHP 8.3 comes with numerous improvements and new features such as:</p><p>For source downloads of PHP 8.3.0 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.3.0">ChangeLog</a>.</p><p>The <a href="https://php.net/manual/en/migration83.php">migration guide</a> is available in the PHP Manual. Please consult it for the detailed list of new features and backward incompatible changes.</p><p>Kudos to all the contributors and supporters!</p></div></div><div><header class="title"><time datetime="2023-11-23T12:24:42+00:00">23 Nov 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.13. This is a bug fix release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.13 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.13">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2023-11-09T09:33:47-08:00">09 Nov 2023</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the release of PHP 8.3.0, RC 6. This is the sixth and final release candidate, continuing the PHP 8.3 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php83">PHP Wiki</a>.</p><p>For source downloads of PHP 8.3.0, RC 6 please visit the <a href="https://downloads.php.net/~eric">download page</a>.</p><p>Please carefully test this version and report any issues found in the <a href="http://bugs.php.net">bug reporting system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.3.0RC6/NEWS">NEWS</a> file or the <a href="https://github.com/php/php-src/blob/php-8.3.0RC6/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be the production-ready, general availability release, planned for 23 November 2023.</p><p>The signatures for the release can be found in <a href="https://gist.github.com/ericmann/ceaadbc09bdbb49efb74212a6c8cf02a">the manifest</a> or on <a href="https://qa.php.net/">the QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></div><div><header class="title"><time datetime="2023-10-26T23:49:55+00:00">26 Oct 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.1.25. This is a bug fix release.</p><p>All PHP 8.1 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.1.25 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.1.25">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2023-10-26T16:39:13+00:00">26 Oct 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.12. This is a bug fix release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.12 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.12">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2023-10-26T15:00:24+00:00">26 Oct 2023</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the release of PHP 8.3.0, RC 5. This is the fifth release candidate, continuing the PHP 8.3 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php83">PHP Wiki</a>.</p><p>For source downloads of PHP 8.3.0, RC 5 please visit the <a href="https://downloads.php.net/~jakub/">download page</a>.</p><p>Please carefully test this version and report any issues found in the <a href="https://github.com/php/php-src/issues">bug reporting system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.3.0RC5/NEWS">NEWS</a> file or the <a href="https://github.com/php/php-src/blob/php-8.3.0RC5/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be the fourth release candidate (RC 5), planned for 26 October 2023.</p><p>The signatures for the release can be found in <a href="https://gist.github.com/bukka/c11ab353c69443c482219515838ed15a">the manifest</a> or on <a href="https://qa.php.net/">the QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></div><div><header class="title"><time datetime="2023-10-12T07:45:43-07:00">12 Oct 2023</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the release of PHP 8.3.0, RC 4. This is the fourth release candidate, continuing the PHP 8.3 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php83">PHP Wiki</a>.</p><p>For source downloads of PHP 8.3.0, RC 4 please visit the <a href="https://downloads.php.net/~eric/">download page</a>.</p><p>Please carefully test this version and report any issues found in the <a href="https://github.com/php/php-src/issues">bug reporting system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.3.0RC4/NEWS">NEWS</a> file or the <a href="https://github.com/php/php-src/blob/php-8.3.0RC4/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be the fifth release candidate (RC 5), planned for 26 October 2023.</p><p>The signatures for the release can be found in <a href="https://gist.github.com/ericmann/5531915317a5186bb4359bdd6c10e299">the manifest</a> or on <a href="https://qa.php.net/">the QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></div><div><header class="title"><time datetime="2023-09-28T18:04:30+00:00">28 Sep 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.1.24. This is a bug fix release.</p><p>All PHP 8.1 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.1.24 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.1.24">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2023-09-28T15:52:06+00:00">28 Sep 2023</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the release of PHP 8.3.0, RC 3. This is the third release candidate, continuing the PHP 8.3 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php83">PHP Wiki</a>.</p><p>For source downloads of PHP 8.3.0, RC 3 please visit the <a href="https://downloads.php.net/~jakub/">download page</a>.</p><p>Please carefully test this version and report any issues found in the <a href="https://github.com/php/php-src/issues">bug reporting system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.3.0RC3/NEWS">NEWS</a> file or the <a href="https://github.com/php/php-src/blob/php-8.3.0RC3/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be the fourth release candidate (RC 4), planned for 12 October 2023.</p><p>The signatures for the release can be found in <a href="https://gist.github.com/bukka/20e2e90e1ef16eb24c333f375203292e">the manifest</a> or on <a href="https://qa.php.net/">the QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></div><div><header class="title"><time datetime="2023-09-28T14:31:39+00:00">28 Sep 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.11. This is a bug fix release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.11 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.11">ChangeLog</a>.</p></div></div><div><header class="title"><time datetime="2023-09-14T03:51:40-07:00">14 Sep 2023</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the release of PHP 8.3.0, RC 2. This is the second release candidate, continuing the PHP 8.3 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php83">PHP Wiki</a>.</p><p>For source downloads of PHP 8.3.0, RC 2 please visit the <a href="https://downloads.php.net/~eric/">download page</a>.</p><p>Please carefully test this version and report any issues found in the <a href="http://bugs.php.net">bug reporting system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.3.0RC2/NEWS">NEWS</a> file or the <a href="https://github.com/php/php-src/blob/php-8.3.0RC2/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be the third release candidate (RC 3), planned for 28 September 2023.</p><p>The signatures for the release can be found in <a href="https://gist.github.com/ericmann/d8c56e1244679ab41672dcfdbea2b0a6">the manifest</a> or on <a href="https://qa.php.net/">the QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></div>]]></description>
      <link>https://www.php.net/index.php#2024-04-24-1</link>
      <guid>https://www.php.net/index.php#2024-04-24-1</guid>
      <pubDate>Wed, 24 Apr 2024 02:00:00 +0200</pubDate>
    </item>
    <item>
      <title><![CDATA[Django 5 and Oracle Autonomous Database - Christopher Jones]]></title>
      <description><![CDATA[<div><div class="hu hv hw hx hy"></div><p id="935b" class="pw-post-body-paragraph mk ml gt mm b mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne nf ng nh gm bj">I’m posting this quick blog in the ‘so I can find it again’ category. The question came up about how to connect to Oracle Autonomous Database using Django and a wallet ZIP file.</p><figure class="nl nm nn no np nq ni nj paragraph-image"><div role="button" tabindex="0" class="nr ns fi nt bg nu"><div class="ni nj nk"><picture><source srcset="https://miro.medium.com/v2/resize:fit:640/format:webp/0*ZvkzEemTBMKX8zZ1 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/0*ZvkzEemTBMKX8zZ1 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/0*ZvkzEemTBMKX8zZ1 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/0*ZvkzEemTBMKX8zZ1 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/0*ZvkzEemTBMKX8zZ1 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/0*ZvkzEemTBMKX8zZ1 1100w, https://miro.medium.com/v2/resize:fit:1400/format:webp/0*ZvkzEemTBMKX8zZ1 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" type="image/webp" /><source data-testid="og" srcset="https://miro.medium.com/v2/resize:fit:640/0*ZvkzEemTBMKX8zZ1 640w, https://miro.medium.com/v2/resize:fit:720/0*ZvkzEemTBMKX8zZ1 720w, https://miro.medium.com/v2/resize:fit:750/0*ZvkzEemTBMKX8zZ1 750w, https://miro.medium.com/v2/resize:fit:786/0*ZvkzEemTBMKX8zZ1 786w, https://miro.medium.com/v2/resize:fit:828/0*ZvkzEemTBMKX8zZ1 828w, https://miro.medium.com/v2/resize:fit:1100/0*ZvkzEemTBMKX8zZ1 1100w, https://miro.medium.com/v2/resize:fit:1400/0*ZvkzEemTBMKX8zZ1 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" /></picture></div></div><figcaption class="nw fe nx ni nj ny nz be b bf z dt">Photo by <a class="af oa" href="https://unsplash.com/@brechtcorbeel?utm_source=medium&amp;utm_medium=referral" rel="noopener ugc nofollow" target="_blank">Brecht Corbeel</a> on <a class="af oa" href="https://unsplash.com/?utm_source=medium&amp;utm_medium=referral" rel="noopener ugc nofollow" target="_blank">Unsplash</a></figcaption></figure><p id="676e" class="pw-post-body-paragraph mk ml gt mm b mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne nf ng nh gm bj">Make sure Django and <a class="af oa" href="https://pypi.org/project/oracledb/" rel="noopener ugc nofollow" target="_blank">python-oracledb</a> are up to date:</p><pre class="nl nm nn no np ob oc od bo oe ba bj">python3 -m pip install Django oracledb --upgrade</pre><p id="af6a" class="pw-post-body-paragraph mk ml gt mm b mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne nf ng nh gm bj">At time of writing, this installed Django 5.0.4 and python-oracledb 2.1.2.</p><h2 id="93f0" class="ol og gt be om on oo dx op oq or dz os mv ot ou ov mz ow ox oy nd oz pa pb pc bj">Oracle ADB-S with 1-way TLS</h2><p id="b295" class="pw-post-body-paragraph mk ml gt mm b mn pd mp mq mr pe mt mu mv pf mx my mz pg nb nc nd ph nf ng nh gm bj">If your <a class="af oa" href="https://cloud.oracle.com/" rel="noopener ugc nofollow" target="_blank">Autonomous Database</a> was created using the ‘Secure access from allowed IPs and VCNs only’ option which gives you 1-way TLS, then you will have allow-listed the machine (or network) where you are running Django. In this case, your Django <code class="cw pi pj pk oc b">settings.py</code> DATABASES entry will be the standard Oracle username/password/connection strings for the database and you don’t need the wallet file. You can find the connection string by clicking the ‘Database connection’ button on the cloud console for the database, Changing the ‘TLS authentication’ drop-down in the ‘Connection Strings’ pane to be ‘TLS’, and then copying one of the connection strings.</p><p id="6bb1" class="pw-post-body-paragraph mk ml gt mm b mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne nf ng nh gm bj">Your Django <code class="cw pi pj pk oc b">settings.py</code> file can then look like:</p><pre class="nl nm nn no np ob oc od bo oe ba bj">DATABASES = {<br />  'default': {<br />    'ENGINE': 'django.db.backends.oracle',<br />    'NAME': '(description= (retry_count=20)(retry_delay=3)(address=(protocol=tcps)(port=1521)(host=xxx.oraclecloud.com))(connect_data=(service_name=xxx_cjdb_high.adb.oraclecloud.com))(security=(ssl_server_dn_match=yes)))',<br />    'USER': 'admin',<br />    'PASSWORD': 'xxxxxxxxxx',<br />  }<br />}</pre><p id="e938" class="pw-post-body-paragraph mk ml gt mm b mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne nf ng nh gm bj">On macOS, if you run your Django <code class="cw pi pj pk oc b">python3 manage.py runserver</code> command and get an error like:</p><pre class="nl nm nn no np ob oc od bo oe ba bj">oracledb.exceptions.OperationalError: DPY-6005: cannot connect to database (CONNECTION_ID=xxxx).<br />[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self-signed certificate in certificate chain (_ssl.c:1000)</pre><p id="2515" class="pw-post-body-paragraph mk ml gt mm b mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne nf ng nh gm bj">you can follow <a class="af oa" href="https://github.com/oracle/python-oracledb/discussions/161#discussioncomment-5512058" rel="noopener ugc nofollow" target="_blank">this solution</a> and first run a command like:</p><pre class="nl nm nn no np ob oc od bo oe ba bj">/Applications/Python\ 3.12/install\ Certificates.command</pre><p id="3ebb" class="pw-post-body-paragraph mk ml gt mm b mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne nf ng nh gm bj">(using the appropriate Python version path).</p><h2 id="ca7b" class="ol og gt be om on oo dx op oq or dz os mv ot ou ov mz ow ox oy nd oz pa pb pc bj">Oracle ADB-S with mTLS</h2><p id="32cf" class="pw-post-body-paragraph mk ml gt mm b mn pd mp mq mr pe mt mu mv pf mx my mz pg nb nc nd ph nf ng nh gm bj">However if your Autonomous Database was created with the ‘Secure access from everywhere’ setting, you will need to download and use the wallet.zip file containing the access certificate from the cloud console.</p><p id="8cbd" class="pw-post-body-paragraph mk ml gt mm b mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne nf ng nh gm bj">Download the wallet file by clicking the ‘Database connection’ button on the cloud console for the database. This will prompt you to create a wallet password.</p><p id="9282" class="pw-post-body-paragraph mk ml gt mm b mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne nf ng nh gm bj">Next, unzip the wallet file — it must be unzipped. In the example below, my directory <code class="cw pi pj pk oc b">/Users/cjones/CJMTLS</code> contains the files:</p><pre class="nl nm nn no np ob oc od bo oe ba bj">  -rw-r--r--@  1 cjones  staff   3029 22 Apr 00:07 README<br />  -rw-r--r--@  1 cjones  staff   5349 22 Apr 00:07 cwallet.sso<br />  -rw-r--r--@  1 cjones  staff   5304 22 Apr 00:07 ewallet.p12<br />  -rw-r--r--@  1 cjones  staff   5710 22 Apr 00:07 ewallet.pem<br />  -rw-r--r--@  1 cjones  staff   3192 22 Apr 00:07 keystore.jks<br />  -rw-r--r--@  1 cjones  staff    691 22 Apr 00:07 ojdbc.properties<br />  -rw-r--r--@  1 cjones  staff    114 22 Apr 00:07 sqlnet.ora<br />  -rw-r--r--@  1 cjones  staff    768 22 Apr 00:07 tnsnames.ora<br />  -rw-r--r--@  1 cjones  staff   2056 22 Apr 00:07 truststore.jks</pre><p id="161f" class="pw-post-body-paragraph mk ml gt mm b mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne nf ng nh gm bj">Then your Django <code class="cw pi pj pk oc b">settings.py</code> file will need to contain this:</p><pre class="nl nm nn no np ob oc od bo oe ba bj">DATABASES = {<br />  'default': {<br />    'ENGINE': 'django.db.backends.oracle',<br />    'NAME': 'cjmtls_high',<br />    'USER': 'admin',<br />    'PASSWORD': 'xxxxxxxxxxxx',<br />    'OPTIONS': {<br />        "config_dir": "/Users/cjones/CJMTLS",<br />        "wallet_location": "/Users/cjones/CJMTLS",<br />        "wallet_password": "xxxxxxxxxx"<br />    }<br />  }<br />}</pre><p id="701b" class="pw-post-body-paragraph mk ml gt mm b mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne nf ng nh gm bj">The NAME field is one of the connection aliases in the <code class="cw pi pj pk oc b">tnsnames.ora</code> file. This file is read from the “config_dir” folder. Note that you have to supply the wallet directory location in “wallet_location”, and also the wallet password to open the PEM file. This is the password you created when you downloaded the wallet.zip file. This password is needed at runtime in the default ‘Thin’ mode of the python-oracledb driver.</p><p id="0dc0" class="pw-post-body-paragraph mk ml gt mm b mn mo mp mq mr ms mt mu mv mw mx my mz na nb nc nd ne nf ng nh gm bj">For python-oracledb Thick mode use — which requires different settings, and for general background, see the python-oracledb doc <a class="af oa" href="https://python-oracledb.readthedocs.io/en/latest/user_guide/connection_handling.html#connecting-to-oracle-cloud-autonomous-databases" rel="noopener ugc nofollow" target="_blank">Connecting to Oracle Cloud Autonomous Databases</a>.</p></div>]]></description>
      <link>https://cjones-oracle.medium.com/django-5-and-oracle-autonomous-database-fc73207bf984?source=rss-adc937c3a9d------2</link>
      <guid>https://cjones-oracle.medium.com/django-5-and-oracle-autonomous-database-fc73207bf984?source=rss-adc937c3a9d------2</guid>
      <pubDate>Mon, 22 Apr 2024 05:17:00 +0200</pubDate>
    </item>
    <item>
      <title><![CDATA[Moving on from Mocha, Chai and nyc. - Evert Pot]]></title>
      <description><![CDATA[<p>I’m a maintainer of several small open-source libraries. It’s a fun activity. If the scope of the library is small enough, the maintenance burden is typically fairly low. They’re usually mostly ‘done’, and I occasionally just need to answer a few questions per year, and do the occasional release to bring it back up to the current ‘meta’ of the ecosystem.</p><p>Also even though it’s ‘done’, in use by a bunch of people and well tested, it’s also good to do a release from time to time to not give the impression of abandonment.</p><p>This weekend I released a 2.0 version of my <a href="https://github.com/evert/bigint-money">bigint-money</a> library, which is a fast library for currency math.</p><p>I originally wrote this in 2018, so the big BC break was switching everything over to <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules" title="JavaScript modules">ESM</a>. For a while I <a href="https://evertpot.com/universal-commonjs-esm-typescript-packages/">tried to support both CommonJS and ESM</a> builds for my packages, but only a year after all that effort it frankly no longer feels needed. I was worried the ecosystem was going to split, but people stuck on (unsupported) versions of Node that don’t support ESM aren’t going to proactively keep their other dependencies updated, so CommonJS is for (and many others) in the past now. (yay!)</p><p>Probably <em>the single best way</em> to keep maintenance burden for packages low is to have few dependencies. Many of my packages have 0 dependencies.</p><p>Reducing <code class="language-plaintext highlighter-rouge">devDependencies</code> also helps. If you didn’t know, <code class="language-plaintext highlighter-rouge">node</code> now has a built-in testrunner. I’ve been using <a href="https://mochajs.org/">Mocha</a> + <a href="https://www.chaijs.com/">Chai</a> for many many years. They were awesome and want to thank the maintainers, but <code class="language-plaintext highlighter-rouge">node --test</code> is pretty good now and has pretty output.</p><p>It also:</p><ul><li>Is much faster (about twice as fast with Typescript and code coverage reporting, but I suspect the difference will grow with larger code bases).</li>
<li>Easier to configure (especially when you’re also using Typescript. Just use <code class="language-plaintext highlighter-rouge">tsx --test</code>).</li>
<li>It can output test coverage with (<code class="language-plaintext highlighter-rouge">--experimental-test-coverage</code>).</li>
</ul><p>Furthermore, while <a href="https://nodejs.org/api/assert.html">node:assert</a> doesn’t have all features of Chai, it has the important ones (deep compare) and adds better Promise support.</p><p>All in all this reduced my <code class="language-plaintext highlighter-rouge">node_modules</code> directory from a surprising 159M to 97M, most of which is now Typescript and ESLint, and my total dependency count from 335 to 141 (almost all of which is ESLint).</p><p>Make sure that Node’s test library, coverage and assertion library is right for you. It may not have all the features you expect, but I keep my testing setup relatively simple, so the switch was easy.</p>]]></description>
      <link>https://evertpot.com/bigint-money-2/</link>
      <guid>https://evertpot.com/bigint-money-2/</guid>
      <pubDate>Sun, 21 Apr 2024 05:00:00 +0200</pubDate>
    </item>
    <item>
      <title><![CDATA[Concealing Cacophony - Derick Rethans]]></title>
      <description><![CDATA[<div class="article">
  <div class="body">
    <div class="articleListItem">
      <h1><a name="concealing_cacophony"></a>Concealing Cacophony</h1>
      <dl class="head"></dl>
      <div class="articleMetaData">
        <div class="date">Tuesday, April 16th 2024, 14:30 BST</div>
        <div class="location"> London, UK</div>
      </div>
      <p>Over the last few weeks I have been publishing a <a href="https://www.youtube.com/watch?v=WjbKYHzoKM0&amp;list=PLg9Kjjye-m1hW4z0J-546qaFpysjlo27x">series of videos</a> on writing PHP extensions.</p>
      <p>I record these videos through <a href="https://obsproject.com/">OBS</a>, and then slice and dice them with <a href="https://kdenlive.org/en/">Kdenlive</a>. This editing is necessary to make up for my mistakes, shorten the time we wait for things to compile, and to remove the noise of me hammering away on my keyboard.</p>
      <p>Editing takes a lot of time, and I still wasn't always pleased with the result as there was still a fair amount of noise while I am talking.</p>
      <p>For the <a href="https://phpinternals.news/">PHP Internals News podcast</a>, I used a set of noise cancellation filters, which worked wonders. But it turns out that Kdenlive does not come with one built in.</p>
      <p>I had a look around on the Internet, and learned that there is a <a href="https://en.wikipedia.org/wiki/LADSPA">LADSPA</a> Noise Suppressor for Voice plugin. LADSPA is an open API for audio filters and audio signal processing effects. LADSPA plugins can be used with Kdenlive.</p>
      <p>Some Linux distributions have a package for this LADSPA Noise Suppressor for Voice, but my Debian distribution bookworm does not.</p>
      <p>I found <a href="https://kentwest.neocities.org/westk/librnnoise">instructions</a> that explain how to build the plugin from source. These instructions worked after some tweaks. I ended up creating the following script:</p>
      <pre>#!/bin/bash

sudo apt install cmake ninja-build pkg-config libfreetype-dev libx11-dev libxrandr-dev libxcursor-dev
git clone https://github.com/werman/noise-suppression-for-voice /tmp/noise
cd /tmp/noise
cmake -Bbuild-x64 -H. -GNinja -DCMAKE_BUILD_TYPE=Release
sudo ninja -C build-x64 install

</pre>
      <p>After running this script, and restarting Kdenlive, I found the installed plugin when I searched for it.</p>
      <p>With the plugin loaded, I now have much clearer sound, and I also don't have to edit the sections where I am typing, as the plugin automatically handles this.</p>
      <p>I will still have to edit out my mistakes.</p>
      <p>I then also had a look at how it worked. It turns out that <a href="https://github.com/werman/noise-suppression-for-voice">this plugin</a> uses neural networks to cancel the noise.</p>
      <p>In the background, it uses the <a href="https://github.com/xiph/rnnoise">RNNoise</a> library which implements an algorithm by Jean-Marc Valin, as outlined in this <a href="https://arxiv.org/pdf/1709.08243.pdf">paper</a>. There is an easier to read version of how the <a href="https://jmvalin.ca/demo/rnnoise/">algorithm works</a> on his website.</p>
      <p>The <a href="https://media.xiph.org/rnnoise/README">data to train the model</a> is also freely available, and uses resources from the <a href="http://www.openslr.org/">OpenSLR</a> project. Noise data is also available there. From what I can tell, all this data was contributed under reasonable conditions, and not scraped from the internet without consent. That is important to me.</p>
      <p>Hopefully, from the third video in the series, you will find the sound quality much better.</p>
      <div class="patreon">
        <a href="https://www.patreon.com/bePatron?u=7864328">
          <img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!">
        </a>
      </div>

    </div>
  </div>
</div>]]></description>
      <link>https://derickrethans.nl/concealing-cacaphony.html</link>
      <guid>https://derickrethans.nl/concealing-cacaphony.html</guid>
      <pubDate>Tue, 16 Apr 2024 15:30:00 +0200</pubDate>
    </item>
    <item>
      <title><![CDATA[Tukio 2.0 released - Event Dispatcher for PHP - Larry Garfield]]></title>
      <description><![CDATA[<header><p>Submitted by Larry on 14 April 2024 - 2:24pm</p>
</header><div class="node__content clearfix"><div class="clearfix text-formatted field field--name-body field--type-text-with-summary field--label-hidden field__item"><p>I've just released version 2.0 of <a rel="noopener noreferrer" target="_blank" href="https://github.com/Crell/Tukio">Crell/Tukio</a>! Available now from your favorite Packagist.org. Tukio is a feature-complete, easy to use, robust Event Dispatcher for PHP, following PSR-14. It began life as the PSR-14 reference implementation.</p><p>Tukio 2.0 is almost a rewrite, given the amount of cleanup that was done. But the final result is a library that is vastly more robust and vastly easier to use than version 1, while still producing near-instant listener lookups.</p><p>Some of the major improvements include:</p><ul><li>It now uses Topological sorting internally, rather than priority sorting. Both are still supported, but the internal representation has changed. The main benefits are cycle detection and support for multiple before/after rules per listener.</li>
<li>The API has been greatly simplified, thanks to PHP 8 and named arguments. It's now down to essentially two methods -- <code>listener()</code> and <code>listenerService()</code>, both of which should be used with named arguments for maximum effect. The old API methods are still supported, but deprecated to allow users to migrate to the new API.</li>
<li>Tukio can now auto-derive more information about your listeners, making registration even easier.</li>
<li>It now uses the powerful <a rel="noopener noreferrer" target="_blank" href="https://github.com/Crell/AttributeUtils">Crell/AttributeUtils</a> library for handling attribute-based registration. That greatly simplified a lot of code while making several new features easy.</li>
<li>Attributes are now supported on the class level, not just method. That makes building single-method listener services trivially easy.</li>
</ul><p><em>Continue reading this post on <a href="https://peakd.com/hive-168588/@crell/tukio-20-released-event-dispatcher-for-php">PeakD</a>.</em></p></div><div class="field field--name-blog-topics field--type-entity-reference field--label-hidden field__items"><p><a href="https://www.garfieldtech.com/topics/web-development/php" hreflang="en">PHP</a></p><p><a href="https://www.garfieldtech.com/taxonomy/term/101" hreflang="en">PHP-FIG</a></p><p><a href="https://www.garfieldtech.com/taxonomy/term/113" hreflang="en">PSR-14</a></p></div></div>]]></description>
      <link>https://www.garfieldtech.com/blog/tukio2-release</link>
      <guid>https://www.garfieldtech.com/blog/tukio2-release</guid>
      <pubDate>Sun, 14 Apr 2024 21:24:00 +0200</pubDate>
    </item>
    <item>
      <title><![CDATA[Check licenses of composer dependencies - Rob Allen]]></title>
      <description><![CDATA[<p>With some commercial projects, it can be useful to know that all your dependencies have licences that your organisation deems acceptable.</p>
<p>I had this requirement for a few clients now and came up with this script that we ran as part of our CI which would then fail if a dependency used a license that wasn't allowed.</p>
<p>This proved to be reasonably easy as <tt>composer licenses</tt> will provide a list of all packages with their license, and more usefully, the <tt>-f json</tt> switch will output the list as JSON. With a machine-readable format, the script just came together!</p>
<p>At some point, we discovered that we needed to allow exceptions for specifically authorised packages, so I added that and haven't changed it since.</p>
<h2>check-licenses.php</h2>
<pre lang="php">
&lt;?php

$allowedLicenses = ['Apache-2.0', 'BSD-2-Clause', 'BSD-3-Clause', 'ISC', 'MIT', 'MPL-2.0', 'OSL-3.0'];
$allowedExceptions = [
    'some-provider/some-provider-php', // Proprietary license used by SMS provider
];

$licences = shell_exec('composer licenses -f json');
if ($licences === null || $licences === false) {
    echo "Failed to retrieve licenses\n";
    exit(1);
}

try {
    $data = json_decode($licences, true, 512, JSON_THROW_ON_ERROR);
} catch (JsonException $e) {
    echo "Failed to decode licenses JSON: " . $e-&gt;getMessage() . "\n";
    exit(1);
}

// Filter out all dependencies that have an allowed license or exception
$disallowed = array_filter(
    $data['dependencies'],
    fn(array $info, $name) =&gt; ! in_array($name, $allowedExceptions)
        &amp;&amp; count(array_diff($info['license'], $allowedLicenses)) === 1,
    ARRAY_FILTER_USE_BOTH
);
if (count($disallowed)) {
    $disallowedList = array_map(
        fn(string $k, array $info) =&gt; sprintf("$k (%s)", implode(',', $info['license'])),
        array_keys($disallowed),
        $disallowed
    );

    printf("Disallowed licenses found in PHP dependencies: %s\n", implode(', ', $disallowedList));
    exit(1);
}

exit(0);
</pre>
<h2>Running check-licenses.php</h2>
<p>If all dependencies are allowed, then <tt>check-licenses</tt> will output nothing and exit with status code <tt>0</tt>:</p>
<pre>
$ php bin/check-licenses.php
$ echo $?
0
</pre>
<p>If at least one dependency is not allowed, then <tt>check-licenses</tt> will list the packages that have licenses that ar not allowed and exit with status code <tt>1</tt>:</p>
<pre>
$ php bin/check-licenses.php
Disallowed licenses found in PHP dependencies: foo/bar (GPL-3.0)
$ echo $?
1
</pre>
<p>Maybe it's useful to others too. If you use it, put it in your CI system.</p>]]></description>
      <link>https://akrabat.com/check-licenses-of-composer-dependencies/</link>
      <guid>https://akrabat.com/check-licenses-of-composer-dependencies/</guid>
      <pubDate>Tue, 09 Apr 2024 12:00:00 +0200</pubDate>
    </item>
    <item>
      <title><![CDATA[Creating JWKS.json file in PHP - Rob Allen]]></title>
      <description><![CDATA[<p>In order to verify a JWT created with an asymmetric key, the verifier needs to get the correct public key. One way to do is described in <a href="https://www.rfc-editor.org/rfc/rfc7517">RFC7517</a> which describes the JSON Web Key format.</p>
<p>Within the header of the JWT there is a <tt>kid</tt> property which is the key ID which is then used to find the correct key within a list provided at the <tt>/.well-known/jwks.json</tt> endpoint.</p>
<p>The JWT header therefore looks something like this:</p>
<pre lang="json">
{
  "alg" : "RS256",
  "kid" : "6eaf334518784ff392c3123b41ae49f5",
  "typ" : "JWT"
}
</pre>
<p>And the <tt>jwks.json</tt> is structured something like this:</p>
<pre lang="json">
{
    "keys": [
        {
            "alg": "RS256",
            "kty": "RSA",
            "use": "sig",
            "kid": "6eaf334518784ff392c3123b41ae49f5",
            "n": "sj6R1AYPKISqYKFxmQMMFJSm583Jfn6ef51SpQPCe17SM10Ljp2YIte924U ...",
            "e": "AQAB"
        }
    ]
}
</pre>
<p>This is an interesting format as it doesn't use the standard PEM format for the key, but rather stores it as a modulus ("n") and exponent ("e") as per <a href="https://datatracker.ietf.org/doc/html/rfc7518#section-6.3">RFC 7518 section 6.3</a>:</p>
<dl>
<dt>6.3.1.1. "n" (Modulus) Parameter</dt>
<dd>The "n" (modulus) parameter contains the modulus value for the RSA<br>
   public key.  It is represented as a Base64urlUInt-encoded value.</dd>
<dd>Note that implementers have found that some cryptographic libraries<br>
   prefix an extra zero-valued octet to the modulus representations they<br>
   return, for instance, returning 257 octets for a 2048-bit key, rather<br>
   than 256.  Implementations using such libraries will need to take<br>
   care to omit the extra octet from the base64url-encoded<br>
   representation.</dd>
<dt>6.3.1.2. "e" (Exponent) Parameter</dt>
<dd>The "e" (exponent) parameter contains the exponent value for the RSA<br>
   public key.  It is represented as a Base64urlUInt-encoded value.</dd>
</dl>
<p>Fortunately, we can use openssl to sort this all out for us:</p>
<pre lang="php">
// $keyString is a PEM encoded public key
$key = openssl_get_publickey($keyString);
$details = openssl_pkey_get_details($key);
</pre>
<p>Assuming <tt>$key</tt> is an instance of <tt>OpenSSLAsymmetricKey</tt> and <tt>$details</tt> is an array, then:</p>
<pre lang="php">
$modulus = $details['rsa']['n'];
$exponent = $details['rsa']['e'];
</pre>
<p>Putting this into a PSR-15 request handler that is passed an array of public keys, we can put together a <tt>jwks.json</tt> response:</p>
<pre lang="php">
&lt;?php

declare(strict_types=1);

namespace App\Handler;

use Laminas\Diactoros\Response\JsonResponse;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;
use Webmozart\Assert\Assert;

class JwksHandler implements RequestHandlerInterface
{
    /**
     * @param string[] $publicKeys
     */
    public function __construct(private readonly array $publicKeys)
    {
    }

    public function handle(ServerRequestInterface $request): ResponseInterface
    {
        $keys = [];

        foreach ($this-&gt;publicKeys as $keyString) {
            $key = openssl_get_publickey($keyString);
            Assert::isInstanceOf(\OpenSSLAsymmetricKey::class, 'Public key is not valid.');

            $details = openssl_pkey_get_details($key);
            Assert::isArray($details, 'Public key details are not valid.');

            $keys[] = [
                'kty' =&gt; 'RSA',
                'alg' =&gt; 'RS256',
                'use' =&gt; 'sig',
                'kid' =&gt; sha1($keyString),
                'n'   =&gt; strtr(rtrim(base64_encode($details['rsa']['n']), '='), '+/', '-_'),
                'e'   =&gt; strtr(rtrim(base64_encode($details['rsa']['e']), '='), '+/', '-_'),
            ];
        }

        return new JsonResponse(['keys' =&gt; $keys]);
    }
}
</pre>
<p>Note that we remove the base64 padding (<tt>=</tt> at the end) and also use the <a href="https://base64.guru/standards/base64url">Base64Url modification</a> where "<tt>+</tt>" is replaced with "<tt>-</tt>" and "<tt>/</tt>" with "<tt>_</tt>".</p>
<p>The other properties in the JSON object are:</p>
<ul>
<li><a href="https://www.rfc-editor.org/rfc/rfc7517#section-4.1"><tt>kty</tt></a>: Key Type – the cryptographic algorithm family used with the key</li>
<li><a href="https://www.rfc-editor.org/rfc/rfc7517#section-4.4"><tt>alg</tt></a>: Algorithm – the specific cryptographic algorithm used.</li>
<li><a href="https://www.rfc-editor.org/rfc/rfc7517#section-4.2"><tt>use</tt></a>: Use – the intended use of the public key. "sig" for signature, "enc" for encryption.</li>
<li><a href="https://www.rfc-editor.org/rfc/rfc7517#section-4.5"><tt>kid</tt></a>: Key ID – used to match a specific key</li>
</ul>
<p>The verifier reads the <tt>jwks.json</tt> file and iterates over the list to find the one that matches the <tt>kid</tt> in the JWT header that they are trying to verify. When they find it, the can then convert the modulus exponent back into a public key and verify the JWT as per usual.</p>]]></description>
      <link>https://akrabat.com/creating-jwks-json-file-in-php/</link>
      <guid>https://akrabat.com/creating-jwks-json-file-in-php/</guid>
      <pubDate>Tue, 26 Mar 2024 12:00:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[A quick guide to JWTs in PHP - Rob Allen]]></title>
      <description><![CDATA[<p>The most common use of JWTs is as an authentication token, usually within an OAuth2 workflow. Creating these tokens is part and parcel of the authentication library that you use.</p>
<p>I recently had a requirement to use a JWT independent of authentication and these are some notes on what I learned when researching with <a href="https://github.com/lcobucci/jwt">Lcobucci\JWT</a>.</p>
<h2>Make up of a JWT</h2>
<p>To really understand JWTs, read <a href="https://datatracker.ietf.org/doc/html/rfc7519#section-1">RFC7519</a>. For a more readable introduction, read the one on <a href="https://jwt.io/introduction">jwt.io</a>.</p>
<p>The most important thing about a JWT is that it contains data and a signature. The signature allows you to verify that the JWT's data hasn't been tampered with. This works because the signature is signed with a secret. This can be a shared secret (a symmetrical algorithm) or a public/private key pair (asymmetric algorithm).</p>
<p>In my case, I'm only interested in signing a JWT using a public/private key as my client cannot securely hold a shared secret.</p>
<h2>Creating a public/private key</h2>
<p><a href="https://www.openssl.org/">OpenSSL</a> is your friend here. Create a <tt>keys</tt> directory and then use the command line.</p>
<p>To create a private key:</p>
<pre>
openssl genpkey -algorithm RSA -out keys/private.key -pkeyopt rsa_keygen_bits:2048
</pre>
<p>To create the public key from the private key:</p>
<pre>
openssl rsa -pubout -in keys/private.key -out keys/public.key
</pre>
<p>You will now have two files in the <tt>keys</tt> directory: <tt>private.key</tt> and <tt>public.key</tt>. Keep <tt>private.key</tt> safe and make <tt>public.key</tt> available to your clients.</p>
<h2>Creating a token</h2>
<p>Using Lcobucci\JWT, we create a <tt>Configuration</tt>:</p>
<pre lang="php">
use Lcobucci\JWT\Configuration;
use Lcobucci\JWT\Signer\Rsa\Sha256;
use Lcobucci\JWT\Signer\Key\InMemory;

$configuration = Configuration::forAsymmetricSigner(
    new Sha256(),
    InMemory::file(__DIR__ . '/keys/private.key'),
    InMemory::file(__DIR__ . '/keys/public.key')
);
</pre>
<p>From our configuration, we can obtain a builder and specify our token:</p>
<pre lang="php">
$keyId = '40597EB1-5E20-49B5-BDDF-B24D1B3B05B5';
$subject = '851828E8-C376-4026-9FD8-D2CCE406CD1C';
$now = new \DateTimeImmutable();

$builder = $configuration-&gt;builder()
    -&gt;identifiedBy($keyId)
    -&gt;relatedTo($subject)
    -&gt;issuedBy('https://app.example.com')
    -&gt;issuedAt($now)
    -&gt;expiresAt($now-&gt;modify('+2 weeks'))
    -&gt;withClaim('foo', 'bar');
</pre>
<p>The data elements in a JWT are called claims. There are a number of <a href="https://datatracker.ietf.org/doc/html/rfc7519#section-4.1">registered claims</a> that are not mandatory, but you should set if they are relevant as all clients will recognise them and their purpose. In particular JWT ID, issuer, subject, issued at and expiration time are particularly useful. There are also a set of <a href="https://www.iana.org/assignments/jwt/jwt.xhtml#claims">public claims</a> that provide a standardised set of key names for common information which help avoid clashes.</p>
<p>Then there is the data specific to your application which are known as private claims. These can be whatever you like and in the example above, we have created a claim called "foo".</p>
<p>Finally we create the token itself:</p>
<pre lang="php">
$token = $builder-&gt;getToken($configuration-&gt;signer(), $configuration-&gt;signingKey());
$tokenString = $token-&gt;toString();
</pre>
<p>We can then send the token string in response to an API request, etc.</p>
<h2>Validating a token</h2>
<p>When we receive a token, we need to validate it. This means that we check that it hasn't been tampered with and we can also check that the data within it is as expected.</p>
<p>Firstly, we parse the token string back into a token object:</p>
<pre lang="php">
use Lcobucci\Clock\SystemClock;
use Lcobucci\JWT\Encoding\JoseEncoder;
use Lcobucci\JWT\Signer\Rsa\Sha256;
use Lcobucci\JWT\Token\Parser;

$parser = new Parser(new JoseEncoder());
$token = $parser-&gt;parse($tokenString);
</pre>
<p>To validate it, we need a validator and a set of constraints that the validator will test the token for:</p>
<pre lang="php">
$validator = new Validator();

$clock = new SystemClock();
$constraints = [
    new SignedWith(new Sha256(), InMemory::file(__DIR__ . '/keys/public.key')),
    new LooseValidAt($clock),
    new IssuedBy('https://app.example.com'),
];
</pre>
<p>The three constraints here check that the JWT:</p>
<ul><li>has been signed with the private key (by using the public key to verify)</li>
<li>is current and has not expired</li>
<li>was issued by the expected issuer</li>
</ul><p>There are other constraints too – check the docs.</p>
<p>Note that the time based constraints use the <a href="https://www.php-fig.org/psr/psr-20/">PSR-20:Clock</a> interface, so we use <a href="https://github.com/lcobucci/clock">Lcobbucci/clock</a> as a</p><p><i>Truncated by Planet PHP, read more at <a href="https://akrabat.com/a-quick-guide-to-jwts-in-php/">the original</a> (another 672 bytes)</i></p>]]></description>
      <link>https://akrabat.com/a-quick-guide-to-jwts-in-php/</link>
      <guid>https://akrabat.com/a-quick-guide-to-jwts-in-php/</guid>
      <pubDate>Tue, 19 Mar 2024 12:00:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[python-oracledb 2.1 and node-oracledb 6.4 have been released - Christopher Jones]]></title>
      <description><![CDATA[<p>I’m still on a long sabbatical so this will be a brief post. In my absence our Oracle Database driver team has been busy and are proud to announce that python-oracledb 2.1 and node-oracledb 6.4 have been released. Also our C Oracle Database Programming Interface for Drivers and Applications <a href="https://github.com/oracle/odpi">ODPI-C</a> 5.2 is available from GitHub.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*Dos0RZy1TlQfXx0M"><figcaption>Photo by <a href="https://unsplash.com/@jingdachen?utm_source=medium&amp;utm_medium=referral">Jingda Chen</a> on <a href="https://unsplash.com/?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><p>You can read about <strong>node-oracledb 6.4</strong> for Node.js in <a href="https://medium.com/u/12606d16645a">Sharad Chandran</a>’s post <a href="https://medium.com/@sharad-chandran/node-oracledb-6-4-offers-improved-lob-and-oson-support-9aab2ec2d899">Node-oracledb 6.4 offers improved LOB and OSON support</a>.</p><p><strong>ODPI-C 5.2</strong> release notes are <a href="https://odpi-c.readthedocs.io/en/latest/releasenotes.html">here</a>.</p><p>To see what’s new in the <strong>python-oracledb 2.1</strong> release for Python, <a href="https://python-oracledb.readthedocs.io/en/latest/release_notes.html#releasenotes">review the release notes</a> and check out the considerable number of enhancements and fixes. Some highlights are:</p><ul><li>asyncio support is out of pre-release status.</li><li>Some of the great behind-the-scenes work to reduce connection establishment timea for Oracle Database can now be used in the python-oracledb’s default Thin mode. (Thick mode will automatically get these benefits when compatible Instant Clients or Oracle Client libraries are used). In addition to the benefits for all Oracle Database 23c users, there is a new, extra option to use “TCP fast open” support when connecting to Oracle Autonomous Database Serverless (ADB-S).</li><li>Ongoing work exposes more of Oracle Database’s advanced JSON support, in particular to let you take advantage of Oracle’s efficient internal storage format (“OSON”) with its extended data types.</li></ul><h3>Installing or Upgrading python-oracledb</h3><p>You can install or upgrade python-oracledb by running:</p><pre>python -m pip install oracledb --upgrade</pre><p>The pip options--proxy and --user may be useful in some environments. See <a href="https://python-oracledb.readthedocs.io/en/latest/user_guide/installation.html">python-oracledb Installation</a> for details.</p><h3>python-oracledb References</h3><p>Home page: <a href="https://oracle.github.io/python-oracledb/index.html">oracle.github.io/python-oracledb/index.html</a></p><p>Installation instructions: <a href="https://python-oracledb.readthedocs.io/en/latest/user_guide/installation.html">python-oracledb.readthedocs.io/en/latest/installation.html</a></p><p>Documentation: <a href="https://python-oracledb.readthedocs.io/en/latest/index.html">python-oracledb.readthedocs.io/en/latest/index.html</a></p><p>Release Notes: <a href="https://python-oracledb.readthedocs.io/en/latest/release_notes.html">python-oracledb.readthedocs.io/en/latest/release_notes.html</a></p><p>Discussions: <a href="https://github.com/oracle/python-oracledb/discussions">github.com/oracle/python-oracledb/discussions</a></p><p>Issues: <a href="https://github.com/oracle/python-oracledb/issues">github.com/oracle/python-oracledb/issues</a></p><p>Source Code Repository: <a href="https://github.com/oracle/python-oracledb">github.com/oracle/python-oracledb</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&amp;referrerSource=full_rss&amp;postId=fbd261c8db1e" width="1" height="1" alt="">]]></description>
      <link>https://cjones-oracle.medium.com/python-oracledb-2-1-and-node-oracledb-6-4-have-been-released-fbd261c8db1e?source=rss-adc937c3a9d------2</link>
      <guid>https://cjones-oracle.medium.com/python-oracledb-2-1-and-node-oracledb-6-4-have-been-released-fbd261c8db1e?source=rss-adc937c3a9d------2</guid>
      <pubDate>Tue, 12 Mar 2024 02:53:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[Disc Golf Discs similar to Remix Discs on Amazon - Brian Moon]]></title>
      <description><![CDATA[<p><img src="https://brian.moonspot.net/images/blog_posts/creature.jpg" alt="Remix Creature"></p>
<p><a href="https://www.amazon.com/s?k=Remix+Disc+Golf">Remix Disc Golf</a> is a brand of disc golf discs that I have only been able to find on Amazon. The seller on Amazon is named Disc Golf Goods. On its <a href="https://www.amazon.com/s?me=A13C1EYGIEX6RU&amp;marketplaceID=ATVPDKIKX0DER">Amazon store page</a>, they sell MVP, Axiom, Remix and other brands of disc golf equipment. The <a href="https://www.amazon.com/sp?ie=UTF8&amp;seller=A13C1EYGIEX6RU&amp;asin=B0C2ZT9KLZ&amp;ref_=dp_merchant_link&amp;isAmazonFulfilled=1">detailed seller information</a> on Amazon says the "Business Name" is MVP Pro Shop, LLC. It is pretty common knowledge that these discs are manufacturered and sold by MVP. The speculation is that they are molds made for other companies (Mint, Thought Space Athletics, and possibly others) which they are selling under the Remix name on Amazon. Many of the reviews mention the discs have cosmetic defects or look like they have been used. That has led some to think these are factory seconds. The cool thing is, they cost less than any of the MVP brands or third party brands for which they are known to manufacturer discs. The discs sell from $9.95 to $12.95.</p>
<p>One thing people are always trying to figure out is what disc from another brand was renamed for a Remix disc. Well, it's not an exact science. Some of them could be rejected molds. So, while they may be very similar to another disc, it could be a mold that was meant for another disc that was not used for that disc. This is pure speculation based on talking to people in the know for almost 28 years of playing disc golf.</p>
<p>Now, there is a site that already has a feature that lets one search for similar discs. It is called <a href="https://trydiscs.com/">Try Discs</a>. Their recommendation engine seems to favor flight number similarities over measurements. And we all know that flight numbers are kind of made up. I decided to use the PDGA specs for approved discs to find the discs most similar to the Remix discs available on Amazon. I did not limit the search to brands that are known or believed to be manufactured by MVP. Perhaps you have a favorite disc from another brand that is similar to a Remix disc. There are more Remix discs approved by the PDGA than are on thist list. However, they are not for sale anywhere I can find. I am not claiming that any of the discs will fly like one another. I am solely comparing the measuerments has observed by the PDGA.</p>
<p>If you are interested in some reviews of Remix Discs, <a href="https://www.youtube.com/@ogdiscgolfer/search?query=remix">Pete Collins</a> has some on his YouTube channel.</p>
<p>All values are centimeters except rim configuration. To determine similarity, diameter and inside rim diameter must to be +/- 0.5cm, height, rim depth, and rim thickness must be +/- 0.2cm (it was 0.1cm in an earlier version of the blog post), and rim configuration must be +/- 1.</p>
<p>For details on these specifications, see the <a href="https://www.pdga.com/files/pdga-technical-standards_2023-12-24_v4_0.pdf">PDGA Technical Standards</a> document.</p>
<div>
<table class="stats"><thead><tr><th class="text">Brand</th>
<th class="text">Name</th>
<th class="number">Diameter</th>
<th class="number">Height</th>
<th class="number">Rim Depth</th>
<th class="number">Inside Rim Diameter</th>
<th class="number">Rim Thickness</th>
<th class="number">Rim Configuration</th>
</tr><tr><th class="text">Remix Disc Golf</th>
<th class="text"><a href="https://www.pdga.com/technical-standards/equipment-certification/discs/battleship">Battleship</a> <br><small>5 / 4.5 / 0 / 2.5</small></th>
<th class="number">21.4</th>
<th class="number">1.8</th>
<th class="number">1.4</th>
<th class="number">18.5</th>
<th class="number">1.4</th>
<th class="number">50.5</th>
</tr></thead><tbody><tr><td class="text">Clash Discs</td>
<td class="text"><a href="https://www.pdga.com/technical-standards/equipment-certification/discs/cherry">Cherry</a> <br><small>5 / 5 / -1 / 1</small></td>
<td class="number">21.4</td>
<td class="number">1.7</td>
<td class="number">1.4</td>
<td class="number">18.5</td>
<td class="number">1.4</td>
<td class="number">51</td>
</tr><tr><td class="text">Clash Discs</td>
<td class="text"><a href="https://www.pdga.com/technical-standards/equipment-certification/discs/berry">Berry</a> <br><small>5 / 5 / -1 / 1</small></td>
<td class="number">21.4</td>
<td class="number">1.7</td>
<td class="number">1.4</td>
<td class="number">18.8</td>
<td class="number">1.3</td>
<td class="number">50.5</td>
</tr><tr><td class="text">Kastaplast</td>
<td class="text"><a href="https://www.pdga.com/technical-standards/equipment-certification/discs/j-rn">Järn</a> <br><small>5 / 3 / 0&amp;nbs</small></td></tr></tbody></table></div><p><i>Truncated by Planet PHP, read more at <a href="https://brian.moonspot.net/discs-similar-to-remix-discs">the original</a> (another 56692 bytes)</i></p>]]></description>
      <link>https://brian.moonspot.net/discs-similar-to-remix-discs</link>
      <guid>https://brian.moonspot.net/discs-similar-to-remix-discs</guid>
      <pubDate>Mon, 26 Feb 2024 23:11:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[How I got Disc Golf Network Pro for FREE for 2024 - Brian Moon]]></title>
      <description><![CDATA[<div><header class="article-header">
<p>Tue, Feb 20, 2024 11:48 AM</p>
</header><section class="article-body"><p><em>Do you plan to go to a DGPT event this year? Are you a PDGA member? Then it could be worth it to buy the Disc Golf Network yearly plan.</em></p><p><a href="https://www.discgolfnetwork.com/">Disc Golf Network</a> (aka DGN) (the media arm of the <a href="https://www.dgpt.com/">Disc Golf Pro Tour</a>) (aka DGPT), announced their new <a href="https://www.discgolfnetwork.com/products-list">pricing tiers for 2024</a> earlier this month. It was met with some mixed reviews. Some users of the service had issues using it the first week. Most of those appear to be due to users needing to update the app on their devices or using older streaming devices that do not support the new 60fps stream. They have updated their <a href="https://www.dgpt.com/news/using-the-new-dgn/">upgrade guide</a>. I experienced this on one of my Roku devices. I was not surprised to be honest. Many of the Roku apps we use on that device are laggy and crash from time to time. It is over 10 years old. The fact that it has kept working at all is a credit to Roku.</p><p>As for the pricing for DGN, there are three tiers: Basic, Standard, and Pro. See the link above for the differences. The pricing ranges from $5.99/mo to $19.99/mo for non-PDGA members. While PDGA members can get Basic for free, Standard for $5.99/mo, and Pro for $12.99/mo. There are also yearly options. Basic for $59.99, Standard for $129.99, and Pro for $239.99 for non-PDGA members. And for PDGA members, Standard for $69.99 and Pro for $139.99. Since Basic is free, there is no yearly option for PDGA members of course. Most people I know that want to consume live disc professional disc golf are PDGA members. While some say you have to factor in the $50 annual PDGA membership cost along with the discounted DGN price, that does not apply to me. I would be renewing my PDGA membership either way. So, I will only be speaking about how and why I chose the option I did based on the discounted PDGA pricing.</p><p>The first question I had to ask is what do I want to pay monthly or go ahead and pay for the whole year? The Standard plan annual cost only saves you $2 for the year. Not a compeling reason to do it in my opinion. The annual cost for Pro actually saves more than the cost of a month, $139.99 one time compared to $12.99/mo over 12 months totaling $155.88. There are some ways to save if you change your plan for certain months for certain events or remember to cancel after the DGPT Finale in October. But, let's be real. I won't remember to do that. Most people won't remember to do that. That is why the subscription model is so popular in the USA. That is how gyms stay in business to be honest. If you are the kind of person that likes to manage subscriptions that way, go for it. If you micro manage it completely and only pay for February through October and upgrade the months of the USDGC and European Open, you could get all of the coverage for as low as $88.89 for the year as a PDGA member. I think I did that math right. You are probably saying "Hey, your headline says you are getting it free for the whole year! What gives?" Yes, let me get to that.</p><p>Here is why I opted for the full year, Pro plan. It’s $139.99 for the year. The kicker for me is that any yearly plan includes two free general adminssion (aka GA) weekend passes to a Disc Golf Pro Tour event as well as 10% off any other DGPT ticket purchases. As a family, we had already booked an AirBnB for Nashville in April to go watch the <a href="https://www.dgpt.com/event/2024-music-city-open/">Music City Open</a> before this announcement was made. My two sons and I are going for all three days. And two other family members will be joining us for Sunday. I had planned to get the weekend VIP pass for myself. So, altogether, our tickets to the Music City Open were going to cost around $350. However, with the yearly DGN option, I get the GA passes for free. And I get a 10% discount on the other tickets. Those ended up costing me around $210 after the discount. So, my savings on tickets (tickets I had already planned to buy before I knew there was a discount available) is around $140. That is the cost of the yearly plan. If you include all of the decimals in all of the math, I technically am spending 17 cents more on the DGN subscription than I am saving on tickets. Would that make a better headline?</p><table class="c8" border="1" cellpadding="2"><tbody><tr><th class="c1">Ticket</th>
<th class="c2">Quantity</th>
<th class="c3">Regular Price</th>
<th class="c3">DGN Discounted Price</th>
</tr><tr><td class="c4">3-Day General Admission</td>
<td class="c5">2</td>
<td class="c6">$116.88 ($58.44/ea)</td>
<td class="c6">FREE</td>
</tr><tr><td class="c4">Sunday General Admission</td>
<td class="c5">2</td>
<td class="c6">$71 ($35.50/ea)</td>
<td class="c6">$64.12 ($32.06/ea)</td>
</tr><tr><td class="c4">3-Day VIP</td>
<td class="c5">1</td>
<td class="c6">$161.68</td>
<td class="c6">$145.62</td>
</tr><tr><td class="c4">Total</td>
<td class="c5">5</td>
<td class="c6">$349.56</td>
<td class="c6">$209.74</td>
</tr><tr><td class="c7" colspan="3">Savings</td>
<td class="c6">$139.82</td>
</tr></tbody></table><p>Having said all that, if you are not really into watching live disc golf and don’t follow the pro scene on social media, the best way to consume the pro tour is next day, post produced coverage on the <a href="https://www.youtube.com/@JomezPro">JomezPro YouTube channel</a>. In the past, their coverage only included the lead group each round. This year, JomezPro are doing <a href="https://www.dgpt.com/news/beyond-the-lead-card/">more comprehensive coverage</a> of the event as a whole. I am sure this is due in part to having multiple winners last season that were not in the lead group in the final round (aka chase card champions). This meant that the JomezPro coverage didn’t include footage (or not much at least) of the actual winner of the event. They were purchased or merged with Disc Golf Network early last year. However, other media companies covered the second and third groups. This year, they didn’t partner with those media companies in the same way which allows JomezPro to use the footage from all groups. Listening to <a href="https://www.youtube.com/live/Pz-E42YNCP0">Jeff Spring on the Staggered Stance podcast</a>, it sounds like they will still be partnering with some of those media companies like <a href="https://www.youtube.com/@AceRunProductions">Ace Run Pro</a> for some things this year as well.</p><p>I forgot to mention that I had a hard time finding information about how to get my free tickets and discounts. After some digging, I found in the <a href="https://discgolfnetwork.wikipage.io/c/1483014154/how+to+redeem+your+additional+benefits+as+a+yearly">DGN support pages</a>. You have to fill out a form which triggers an email which has discount coupon codes and a link to another form you have to fill out to get your free DGPT tickets. So, if you get an annual subscription, be sure and fill out this form to at least get your 20% discount codes for the DGPT Pro Shop and JomezPro Shop. JomezPro has made some cool stamps in the past that I have rarely bought unless they had a sale going. Having a 20% discount code will make me consider them more often when ordering discs online.</p><p><em>This post was not paid for or done as a favor for the DGPT. I am just a disc golf fan that wanted to share my experience.</em></p></section><footer class="article-footer"><p><a href="https://brian.moonspot.net/disc-golf-network-pro-for-free-2024#comments">Comments (0)</a></p>
<p><a href="https://brian.moonspot.net/disc-golf-network-pro-for-free-2024">Permalink</a></p>
</footer></div><p>Comments are disabled for this post.</p>]]></description>
      <link>https://brian.moonspot.net/disc-golf-network-pro-for-free-2024</link>
      <guid>https://brian.moonspot.net/disc-golf-network-pro-for-free-2024</guid>
      <pubDate>Tue, 20 Feb 2024 18:48:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[New edition for the Rector Book - Matthias Noback]]></title>
      <description><![CDATA[<p><a href="https://leanpub.com/rector-the-power-of-automated-refactoring"><img src="https://matthiasnoback.nl/assets/2024/rector_book.png" alt="The cover of the 2024 Edition of the Rector book" title="" class="img-thumbnail-portrait pull-right" /></a></p><p>A couple of weeks ago, Tomas Votruba emailed me saying that he just realized that we hadn't published an update of the book we wrote together <em>since December 2021</em>. The book I'm talking about is "Rector - The Power of Automated Refactoring". Two years have passed since we published the current version. Of course, we're all very busy, but no time for excuses - this is a book about keeping projects up-to-date with almost no effort... We are meant to set an example here!</p>
<p>In the meantime, a lot has changed. Tomas has become a very successful legacy-project-saver, with this incredibly powerful tool called Rector. The project has gained a lot of traction in the PHP development community. Tomas and the co-authors of the project keep improving the tool, making it more useful, developer-friendly, faster, and more stable every day. Recently he released version 1.0 on-stage at Laracon Europe, in Amsterdam. In important moment, which indicates that we are dealing with a mature tool.</p>
<p>I know Tomas as a hard worker. He'll do everything to Get Things Done. He keeps simplifying things, even in the Git project that's behind the book's manuscript. Always looking for ways to prevent developer (or writer) mistakes and to automate common tasks, he ruthlessly cuts away unnecessary weight. When he reads a convoluted paragraph that works around some quirk in Rector, he fixes the issue in Rector, so the text is once more easy to understand. If people ask the same questions over and over again, he adds a helpful command to Rector's command-line interface, so the question will disappear. In other words, he has a great idea for feedback. What kind of signal does the code give us? Is this too hard to work with? Can we simplify this? What kind of signal do we get from readers? Let's improve!</p>
<p>With a 1.0 version for Rector also comes a new version of the book about Rector. This 2024 Edition provides an even better start for your static analysis &amp; automated refactoring journey. I can testify personally: once you start, you'll never want to go back.</p>
<p>Read more about the updates on Tomas' blog: <a href="https://tomasvotruba.com/blog/rector-book-2024-release-with-brand-new-chapter">Rector Book 2024 Release with Brand new Chapter</a></p>
<p>And <strong>get the new version here</strong>: <a href="https://leanpub.com/rector-the-power-of-automated-refactoring">https://leanpub.com/rector-the-power-of-automated-refactoring</a></p>
<p>If you already bought a previous version, you can download the latest files for free (of course!).</p>]]></description>
      <link>https://matthiasnoback.nl/2024/02/new-edition-for-the-rector-book/</link>
      <guid>https://matthiasnoback.nl/2024/02/new-edition-for-the-rector-book/</guid>
      <pubDate>Mon, 12 Feb 2024 10:30:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[OAuth2 client updates - Evert Pot]]></title>
      <description><![CDATA[<p>I just released v2.3.0 of <a href="https://www.npmjs.com/package/@badgateway/oauth2-client"><code class="language-plaintext highlighter-rouge">@badgateway/oauth2-client</code></a>, which I wrote because there weren’t any lean, 0-dependency oauth2 clients with modern features such as <a href="https://datatracker.ietf.org/doc/html/rfc7636">PKCE</a>.</p><p>I just released v2.3.0, which includes support for:</p><ul><li>Resource Indicators for OAuth 2.0 (<a href="https://datatracker.ietf.org/doc/html/rfc8707" title="https://datatracker.ietf.org/doc/html/rfc8707">RFC8707</a>).</li>
<li>OAuth2 Token Revocation (<a href="https://datatracker.ietf.org/doc/html/rfc7009" title="OAuth 2.0 Token Revocation">RFC7009</a>).</li>
</ul><p>Hope you like it!</p>]]></description>
      <link>https://evertpot.com/oauth2-client-updates/</link>
      <guid>https://evertpot.com/oauth2-client-updates/</guid>
      <pubDate>Mon, 05 Feb 2024 16:00:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[Friday Night Dinner: East Street by Tampopo - Derick Rethans]]></title>
      <description><![CDATA[<div class="articleMetaData"><p>Friday, January 26th 2024, 18:30 GMT</p><p>3–5 Rathbone Place, London W1T 1HJ, UK</p><p><a href="https://tampopo.co.uk/fitzrovia/">https://tampopo.co.uk/fitzrovia/</a></p><p>Food: £50; Drinks: £35</p></div><p>The idea behind going for a different restaurant every Friday is to try out a wide variety of places, but also of cuisines. We are lucky that in London, we have access to pretty much any sort of dishes we fancy.</p><p>Sometimes, you can even find a wide variety of different culture's food in one place, and East Street is such an establishment. It is situated just North of Oxford Street, close to Tottenham Court Road station. It specialised in what can only be described as pan-Asian.</p><p>Their menu is extensive, from Szechuan dishes via Japan and Korea to Indonesian and Malay. We started with two of their small plates, the Malaysian Satay Chicken and Korean Popcorn Chicken. They were both delicious, very flavourful and moorish. Good Satay Chicken I remember from my parent's Indonesian friends, and this was just like it. With our starters, we enjoyed a lovely Hokkaido Negroni as we didn't think a bottle of wine would fit with this menu.</p><p>Choosing the small plates was hard, as there are so many nice sounding ones. Instead of ordering them all, we also picked a large plate each. I ordered a Rendang Beef Curry, again, with memories of the Indonesian Restaurants you find in the Netherlands. It was accompanied by rice, peanuts, boiled eggs, and some pickled cucumber. My companion ordered a Tamarind Chicken, slices of well cooked moist chicken in a delicious sticky tamarind sauce. It came served with rice, broccoli and crispy onions, this was one of the non-spicy options on the menu, but despite the lack of chillies still had a bit of a kick. Again, not wanting wine, we picked a bog-standard Tiger beer to wash all the delicious flavours down, which paired pretty well.</p><p>Although we were pretty full, we could not quite resist the churros, and shared three with a tasty caramel sauce. I don't quite understand how they fit in an Asian kitchen, but they were delightful regardless.</p><p>If we were to return, which seems likely, we would probably have a meal made up of more of the smaller dishes (all of which sounded delicious) instead of going for the traditional starter plus main course approach.</p><p>The place was pretty full, and when we left I remarked that we were probably amongst the oldest of the clientele, but we didn't feel out of place. Which I think is a good sign.</p>]]></description>
      <link>https://derickrethans.nl/east-street.html</link>
      <guid>https://derickrethans.nl/east-street.html</guid>
      <pubDate>Fri, 26 Jan 2024 19:30:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[Friday Night Dinner: Empire Empire - Derick Rethans]]></title>
      <description><![CDATA[<p>We visited Empire Empire on a chilly January evening. The restaurant was fairly quiet but even at 18.30 there were some tables seated and enjoying their food.</p><p>The restaurant features an old fashioned jukebox type vinyl record player close to the entrance and has a photobooth for some fun snaps should you be so inclined.</p><p>We had a beer each from 40ft Brewery in Hackney, which was lovely. It's great to see an Indian restaurant branching out from the usual cobra and kingfisher options. We started with poppadoms and dips, and then I had a well spiced biryani with incredibly tender lamb falling off the shank and a pastry lid. My companion really enjoyed her Empire Butter Chicken and a naan bread. This was not as rich as some butter chicken curries, but was incredibly flavourful with a nice level of spicing and kick. Unfortunately we were both too full to move onto try what sounded like tasty desserts from the menu.</p><p>Service at Empire Empire was very welcoming and attentive (and quick, but not rushed) we were out and heading home on the bus about an hour after sitting down.</p>]]></description>
      <link>https://derickrethans.nl/empire-empire.html</link>
      <guid>https://derickrethans.nl/empire-empire.html</guid>
      <pubDate>Fri, 19 Jan 2024 19:30:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[Friday Night Dinner: Lokkanta - Derick Rethans]]></title>
      <description><![CDATA[<div class="article">
  <div class="body">
    <div class="articleListItem fridayNightDinner">
      <h1><a name="friday_night_dinner_lokkanta"></a>Friday Night Dinner: Lokkanta</h1>
      <dl class="head"></dl>
      <div class="articleMetaData">
        <div class="date">Friday, January 5th 2024, 18:30 GMT</div>
        <div class="location"> 31 Westbourne Grove, London W2 4UA, United Kingdom</div>
        <div class="url">
          <a href="https://derickrethans.nl%20https//lokkantaturkishrestaurant.co.uk/"> https://lokkantaturkishrestaurant.co.uk/</a>
        </div>
        <div class="costs"> Food: £45, Drinks: £25</div>
      </div>
      <p>As first restaurant of the year, we wanted something low-key. Not far from Paddington station, on Westbourne Grove, there is a whole row of such places. We settled on Lokkanta, a place that specialises in Turkish food.</p>
      <p>We started off with Turkish sausage slices with halloumi, while we were waiting for our main course. At the same time, we started enjoying our delicious red wine from Turkey.</p>
      <p>The front section of the restaurant features a well ventilated charcoal grill upon which most of the meats were roasted. In my case, a well cooked and flavoured lamb shish. My partner picked a Yogurtly Adana, minced grilled lamb with bread and basted in a tomato sauce and yoghurt.</p>
      <p>The service was speedy, and we did not have to wait long. Perhaps that was mostly because when we arrived at 18:30, there was only other table enjoying dinner, so we were almost the only customers. When we left, there were a few more people enjoying their dinner. However, with the restaurant being quite empty, it perhaps lacked a bit of ambience and the tiled interior made it feel a little clinical, I think it would be quite different if it was busy with plenty of hustle and bustle.</p>
      <p>In short, the food and wine was good, but the atmosphere was unfortunately missing.</p>
      <div class="patreon">
        <a href="https://www.patreon.com/bePatron?u=7864328">
          <img src="https://derickrethans.nl/images/become_a_patron_button.png" alt="Become a Patron!">
        </a>
      </div>

    </div>
  </div>
</div>]]></description>
      <link>https://derickrethans.nl/lokkanta.html</link>
      <guid>https://derickrethans.nl/lokkanta.html</guid>
      <pubDate>Fri, 05 Jan 2024 19:30:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[Friday Night Dinner: Ma Petite Jamaica - Derick Rethans]]></title>
      <description><![CDATA[<div class="articleMetaData"><p>Friday, December 29th 2023, 18:30 GMT</p><p>4-6 Inverness Street, London, NW1 7HJ, UK</p><p><a href="https://www.mapetitejamaica.com/">https://www.mapetitejamaica.com/</a></p><p>Food: £65, Drinks: £25</p></div><p>What do you need on a cold and dark winter evening? Exactly, a bit of tropical warmth. Our booking was a little last minute, as we hadn't really thought about arranging something for the last Friday of the year. My wife, who often takes the lead in picking our Friday evening restaurant, suggested this Jamaican place in Camden, not too far from where we live.</p><p>We arrived to find the dining room partially full, with Jamaican musing playing and (fake) palm trees. It gave a happy and homely feel to the dining room.</p><p>I had never had Jamaican food, so decided that I wanted to try the staples. As my starter I picked the ackee and salt fish, which was served with fried dumplings. My wife chose the chickpea and pumpkin curry. We also decided to share a portion of the jerk chicken spring rolls. All three small plates were very flavourful. With enough hints of scotch bonnets to add a kick, but nothing too overpowering. The dumplings were great for dipping up the sauces.</p><p>Because we felt we needed to escape from the cold, we enjoyed a pair of Jamaican Mule cocktails, with our starters, and later mains. The first set was half price as it was still happy hour! There were also a number of Jamaican beers on offer, with a Red Stripe on tap.</p><p>I selected the curried goat with rise and peas as my main course. My wife wanted to order a wrap, which they were no longer serving, although they were on the menu. She ended up with their vegetable curry with a roti. Both were excellent.</p><p>Our only regret was probably ordering too much food. One and a half starter, and a full main per person was certainly too much. But that's not the worst problem to have if your dinner was so tasty.</p>]]></description>
      <link>https://derickrethans.nl/ma-petite-jamaica.html</link>
      <guid>https://derickrethans.nl/ma-petite-jamaica.html</guid>
      <pubDate>Fri, 29 Dec 2023 19:30:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[Friday Night Dinner: Noon - Derick Rethans]]></title>
      <description><![CDATA[<div class="articleMetaData"><p>Friday, December 22nd 2023, 18:30 GMT</p><p>Griend 7, 6221 AJ Maastricht, The Netherlands</p><p><a href="https://noonmaastricht.nl/">https://noonmaastricht.nl/</a></p><p>Food: €70, Drinks: €26</p></div><p>Even when we're out of the country, we try to keep our tradition in place, and so we found ourselves on a cold and rainy evening at Noon, in Maastricht, in the Netherlands.</p><p>When we arrived just after 18:00, the restaurant was already quite full. With a few dozen tables, some high tables, and a bar where a bar keep was making plenty of colourful cocktails. We were seated at a high table right in the middle of the stylishly appointed establishment.</p><p>While enjoying a glass of cava, we shared a couple of starters. The Drunken Salmon (salmon cured in gin and yoghurt), and the Asian slow-roasted Pork Belly. Both were excellent. Flavourful and succulent.</p><p>For my main, I chose the Asian Ribs. I realised it was another Asian-flavoured dish — I know, "Asia" isn't a country. I am usually not keen on ribs, but these were boneless, and that made all the difference. That, and the lovely, and slightly spicy sauce that was slathered over the ribs with a few tiny bits of red chilli.</p><p>My partner's choice was the butter steak, medium rare. That came with carrots and a delicious mushroom foam. The sauce was made with Pedro Ximénez sherry, and had a nice shine to it. With our mains, we each enjoyed a glass of Merlot. The only (minor) let down were their chips that were served with our mains. They were slightly chewy.</p><p>It was a very enjoyable meal in a charming environment, and with very reasonable prices. A great birthday meal!</p>]]></description>
      <link>https://derickrethans.nl/noon.html</link>
      <guid>https://derickrethans.nl/noon.html</guid>
      <pubDate>Fri, 22 Dec 2023 19:30:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[Advent 2023: PSR-15 - Matthew Weier O'Phinney]]></title>
      <description><![CDATA[<p>I've mentioned a few times over the course of this <a href="https://mwop.net/blog/tag/advent2023">2023 Advent series</a> that the longer I'm in the tech field, the more I appreciate and favor <em>simple</em> solutions. I was reminded of this yesterday when I <a href="https://masteringlaravel.io/daily/2023-12-13-why-we-dont-use-return-types-on-controller-actions">read this article on return types in Laravel controllers</a> by <a href="https://joelclermont.com/">Joel Clermont</a>.</p><blockquote>
<h4>Request</h4>
<p>Please, <em>please</em>, <strong><em>please</em></strong> do not take this as an attack on Laravel or on Joel. I have nothing but respect for Joel, and while I'm not a fan of Laravel, I'm also not a hater. It's never a bad thing to have a popular framework that brings folks to a language; Laravel has done that in spades for PHP.</p>
</blockquote><h3>Summarize the article, already...</h3><p>In the article, Joel notes the problem with providing return types in a Laravel controller is due to the fact that it could return a view, a JSON response, an array, a redirect, or more. If there are multiple types that could be returned, based on the request context, you would need to provide a union type. And if you refactor or make changes to the controller later that result in new types being returned, you now need to remember to change the return type declaration.</p><p>In other words, it introduces brittleness.</p><h3>So what?</h3><p>I've worked on multiple iterations of a major MVC framework, and I ran into these same issues. As PHP's type system got incrementally better, the cracks in how frameworks interact with controllers became more evident. Personally, I find the increasing number of type capabilities in PHP to be a huge boon in helping the correctness of applications, and preventing whole classes of errors. But if the framework <em>prevents</em> you from using the type system, or makes adding type declarations into a situation that can now introduce errors, it puts the developer and maintainer of an application into a problematic situation.</p><h3>What are the alternatives?</h3><p>I worked for quite some time on <a href="https://www.php-fig.org/psr/psr-7">PSR-7 HTTP Message Interfaces</a>, largely so that we could have a proper HTTP message abstraction in PHP on which to build a better foundation for applications and frameworks. From this emerged <a href="https://www.php-fig.org/psr/psr-15">PSR-15 HTTP Server Request Handlers</a> (which I sponsored and collaborated on, but was not primary author of).</p><p>What I love about PSR-15 is that there is no ambiguity about what you return from middleware or a handler. You return a response. That's <em>all</em> you can return.</p><p>This means there's no magic about different return values resulting in different behavior from the framework. You don't need to keep a mental map about what will happen, or do a deep dive into the framework internals to understand the ramifications of returning a view versus an array.</p><p>Instead, your handler will <em>create a response</em>, and provide the logic for how that is done. If you need HTML, you render a template, and feed it to the response. If you need JSON, you serialize data to JSON, and feed it to the response. If you need a redirect, you create a response with the appropriate status code and <code>Location</code> header. And so on and on.</p><p>Yes, this can lead to a little extra code at times, but:</p><ul><li>You can see <em>exactly</em> what you intend to return to the user, and <em>why</em>.</li>
<li>If you try and return anything <em>but</em> a response, it'll result in a <code>TypeError</code>.</li>
<li>You can test all of the different possible returns easily, by doing assertions on the returned response based on different requests provided to the handler or middleware.</li>
</ul><p>But should you do <em>everything</em> in a handler? What about things that will happen for whole sections of the site, or will be repeated in many locations, like initializing a session, or checking for an authenticated user, or validating headers, or caching?</p><p>For those things, PSR-15 provides <em>middleware</em>. These are expected to be chained together, like a pipeline or a command bus, and the request is passed down through them, and a response returned on the way back up. They're a powerful way to provide re-usable pieces of functionality to your application.</p><p>What's more, using middleware is often far easier to understand than how and when various events will intercept a request. You can see the list of middleware for a given handler, and understand that they act either as filters on the incoming request (authentication, caching, etc.), or as decorators on the response (e.g. encoding or compressing the response, caching, etc.). Since each does exactly one thing (ideally), you can test how each works, and understand how and when to compose each, and how they might work in combination.</p><p>Building complex behavior via piping one thing to another is hugely powerful. There's a reason that the <a href="https://en.wikipedia.org/wiki/Unix_philosophy">Unix Philosophy</a> has existed as long as it has, and I can appreciate an approach to web development that builds on it.</p>]]></description>
      <link>https://mwop.net/blog/2023-12-14-advent-psr-15.html</link>
      <guid>https://mwop.net/blog/2023-12-14-advent-psr-15.html</guid>
      <pubDate>Fri, 15 Dec 2023 00:21:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[Advent 2023: Doctrine DBAL - Matthew Weier O'Phinney]]></title>
      <description><![CDATA[<p>I've mostly taken database abstraction for granted since I started at Zend. We had a decent abstraction layer in ZF1, and improved it for ZF2. There were a lot quirks to it — you really had to dive in and look at the various SQL abstraction classes to understand how to do more complex stuff — but it worked, and was always right there and available in the projects I worked on.</p><p>In the last couple of years, though, we came to the realization in the Laminas Project that we didn't really have anybody with the expertise or time to maintain it. We've marked it security-only twice now, and while we've managed to keep it updated to each new PHP version, it's becoming harder and harder, and whenever there's a CI issue, it's anybody's guess as to whether or not we'll be able to get it resolved.</p><p>My alternatives have been straight PDO, or Doctrine DBAL, with the latter being my preference.</p><h3>Doctrine <em>what</em>?</h3><p>When most folks who use PHP hear "Doctrine", they immediately think "<a href="https://en.wikipedia.org/wiki/Object%E2%80%93relational_mapping">ORM</a>"; it's how most folks use it, and what it's best known for.</p><p>Underlying the ORM is its database abstraction layer (hence "DBAL"). This library exposes an API that will work across any database it supports; this is essentially what zend-db, and later laminas-db, were doing as well. What most folks don't realize is that you can use the DBAL <em>by itself</em>, without the ORM.</p><h3>Why no ORM?</h3><p>ORMs are fine. Really. But they add an additional layer of complexity to understanding what you are actually doing. Additionally, if you want to do something that doesn't quite fit how the ORM works, you'll need to drop down to the DBAL anyways. So my take has always been: why not just use the DBAL from the beginning?</p><p>So, how does <em>Matthew</em> write code that interacts with the database?</p><p>I start by writing value objects that represent discrete aspects of the application. Most of my work will be in consuming or creating these. From there, I write a <em><a href="https://martinfowler.com/eaaCatalog/repository.html">repository</a></em> class that I use for purposes of persisting and retrieving them. I can usually extract an interface from this, which aids in my testing, or if I decide I need a different approach to persistence later.</p><p>I push the work of mapping the data from the database to these objects, and vice versa, either in the repository, or in the value objects themselves (often via a <a href="https://verraes.net/2014/06/named-constructors-in-php/">named constructor</a>). Using these approaches creates lean code that can be easily tested, and for which there's no real need to understand the underlying system; it's all right there in what I've written for the application.</p><h3>Some gripes about the documentation, and some tips</h3><p>The <a href="https://www.doctrine-project.org/projects/doctrine-dbal/en/current/index.html">Doctrine DBAL docs</a> are a bit sparse, particularly when it comes to its <a href="https://www.doctrine-project.org/projects/doctrine-dbal/en/current/reference/query-builder.html">SQL abstraction</a>. And there's no "getting started" or "basic usage" guide. In fact, it's not until the third page within the docs that you get any code examples; thankfully, at that point they give you information on how to get a database connection:</p><pre class="language-php">use Doctrine\DBAL\DriverManager;
$connectionParams = [
    'dbname'   =&gt; 'mydb',
    'user'     =&gt; 'user',
    'password' =&gt; 'secret',
    'host'     =&gt; 'localhost',
    'driver'   =&gt; 'pdo_mysql',
];
$conn = DriverManager::getConnection($connectionParams);
</pre><p>They also provide a number of other approaches, including using a DSN (an acronym they never explain, but based on using PDO, likely means "data source name").</p><p>Once you have a connection, what do you do? Well the DBAL connection allows you to prepare and execute queries, including via the use of prepared statements. It provides a variety of methods for fetching individual or multiple rows, with a variety of options for how the data is returned (indexed arrays, associative arrays, individual columns, individual values, etc.). These retrieval methods are mirrored in the result instances returned when executing prepared statements as well.</p><p>And that brings me to the SQL abstraction.</p><p>First, it's really, really good. It's minimal, but it covers just about anything you need to do. If you need to write something complex, you probably can; the beauty is that if you can't, you can always fall back to a SQL query, and using the connection's API for binding values.</p><p>But the documentation could be better.</p><p>It felt like it was written by a database admin who has forgotten more than most people ever learn about databases, and never considered that others might not know as much as them. The fact that it starts with architecture and not usage feels hugely antagonistic for somebody coming in just wanting to know how to connect to the database, build a query, and fetch some results. (The irony is not lost on me that this is almost exactly how Laminas and Mezzio docs are written, and, yes, I recognize we could all do better!)</p><blockquote>
<p>Before folks start grousing, yes, I have on my TODO list an item for contributing to the DBAL docs. I'm trying to work up an outline of what I would have found useful, what acronyms need explanation, and some examples of common patterns before I make any suggestions, however.</p>
</blockquote><p>First, they have a whole documentation page related to the SQL query builder, and a lot of examples. But not a single one details <em>how to actually execute the query</em>! So, for those wondering:</p><pre class="language-php">$sql = $conn-&gt;createQueryBuilder();
// ... build your query ...
// Execute a query that will retrieve results (generally SELECT queries):
$result = $sql-&gt;executeQuery();
// Execute a query that produces changes (INSERT, UPDATE, DELETE, etc.):
$count = $sql-&gt;executeStatement();
</pre><p>Query results have a variety of <code>fetch*()</code> operations on them, while executing a statement returns an integer indicating the number of rows affected (assuming the database supports this).</p><p>Second, when I started doing joins, the argument names were confusing, and made it harder to understand what was needed. I eventually figured it out, but it was really easy to flip the arguments for the different tables being joined. The usage below illustrates names that would better describe how to use it:</p><pre class="language-php">$sql-&gt;innerJoin(
    $primaryTableOrItsAliasIfYouSpecifiedOne, // e.g. "user" or "u"
    $newTableToJoin,                          // e.g. "address"
    $aliasForNewTableToJoin,                  // e.g. "a"
    $conditionToJoinOn                        // e.g. "u.id = a.uid"
);
</pre><p>Third, there's some odd differences in the API between INSERT and UPDATE operations., When setting a value, one takes <code>setValue()</code>, while the other takes <code>set()</code>, and only one of these is valid for a given operation (it's <code>setValue()</code> for INSERT operations, and <code>set()</code> for UPDATE operations, in case you were wondering). This is especially confusing when using bound parameters, because <em>both</em> can use the <code>setParameter()</code> method for binding positional placeholder values.</p><p>Speaking of plaeholders, the docs don't do a great job of detailing how to handle <em>placeholders</em> gracefully.</p><p>The documentation suggests patterns like this:</p><pre class="language-php">$queryBuilder
    -&gt;select('id', 'name')
    -&gt;from('users')
    -&gt;where('email = ?')
    -&gt;setParameter(0, $userInputEmail);
</pre><p>Which is fine when there's only one parameterized value, but what if you have several, or if you're dynamically building the query (e.g., looping through user-supplied sorting or criteria, etc.), and you don't know their exact position in the final query? And what if you want to use named parameters instead of positional parameters, but you're not sure if your database supports them?</p><p>The answer is in the docs, but the various <em>examples</em> don't use the pattern (other than in the discussion of the methods), which is infuriating. The above can also be written as follows:</p><pre class="language-php">$queryBuilder
    -&gt;select('id', 'name')
    -&gt;from('users')
    -&gt;where('email = ' . $queryBuilder-&gt;createNamedParameter($userInputEmail));
</pre><p>There's also a <code>createPositionalParameter()</code> method. Both accept an optional second argument, where you can specify the value <em>type</em>, which can help ensure that values are quoted correctly for the SQL type they will map to. This also allows you to do <code>IN()</code> operations, and each value will be quoted correctly, with the appropriate list separator for the database.</p><p>Once you know this approach, it's easy to remember and use, but it took me a few times through the docs before I stumbled across it.</p><p>The SQL it generates, though, is great, and when I've used tools like ZendHQ's Z-Ray to introspect queries, I'm always impressed by what was actually sent over the wire.</p><p>But for all these issues, the fact is that the docs generally give you <em>enough</em>, and the API is so clean and reasonably documented that you can generally figure out how things work just from your IDE hints and autocompletion. Yes, I have gripes, but the library is <em>very</em> solid, <em>very</em> well written, and absolutely something I can depend on.</p><h3>Final Thoughts</h3><p>I've often used straight PDO for projects, and it works fine. However, having a tool available like Doctrine DBAL has been a huge boon in ensuring I can switch from SQLite while prototyping to MySQL for production, and know that things will "just work".</p><p>I also find the way it juggles <em>types</em> to be really useful. I know that if a value is typed in the database as a NULL or as text or as a float or integer, I'll actually get those types back when I query; the same is true for when I send data to the database. There's no magic involved, and I don't have to remember to do type conversions to and from the database. That's <em>exactly</em> the type of functionality I want from a DBAL.</p><p>Yes, writing database-centric code is cumbersome, and there's a reason folks use ORMs, ActiveRecord, and the like. However, it generally only needs to be written once, with occasional updates. Having a good DBAL available helps keep complexity of your application down and gives you the tools to communicate securely with your database.</p>]]></description>
      <link>https://mwop.net/blog/2023-12-10-advent-dbal.html</link>
      <guid>https://mwop.net/blog/2023-12-10-advent-dbal.html</guid>
      <pubDate>Sun, 10 Dec 2023 18:00:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[Advent 2023: Forms - Matthew Weier O'Phinney]]></title>
      <description><![CDATA[<p>The first thing I was tasked with after I moved full time to the Zend Framework team (17 years ago! Yikes!) was to create a forms library. Like all the work I did for ZF in the early days, I first created a working group, gathered requirements, and prioritized features. There were a <em>lot</em> of requests:</p><ul><li>Ability to normalize values</li>
<li>Ability to validate values</li>
<li>Ability to get validation error messages</li>
<li>Ability to render HTML forms, and have customizable markup</li>
<li>Ability to do nested values</li>
<li>Ability to handle optional values</li>
<li>Ability to report missing values</li>
</ul><p>and quite a lot more. But those are some of the things that stuck out that I can remember off the top of my head.</p><p><a href="https://framework.zend.com/manual/1.12/en/zend.form.html">Zend_Form</a> was considered a big enough new feature that we actually bumped the version from 1.0 to 1.5 to call it out.</p><p>And, honestly, in hindsight, it was a mistake.</p><h3>A mistake?</h3><p>Considering the timeframe when I was developing Zend_Form, it was actually a good effort, and it's still one of those features that folks tell me sold them on the framework. But within a year or two, I was able to see some of the drawbacks.</p><p>I first realized the issues when we started integrating the <a href="https://dojotoolkit.org/">Dojo Toolkit</a> with ZF. We ended up having to create first a suite of Dojo-specific form elements, and second a whole bnch of Dojo-specific <em>decorators</em>, which were what we used to render form elements. While the library gave us this flexibility, I saw a few issues:</p><ul><li><strong>Duplication.</strong> We had multiple versions of the same form elements, and it was actually possible to get the wrong version for your form context. And with duplication comes increased maintenance: any time we fixed an issue in one element, we had to check to see if the same issue existed with the Dojo versions, and fix them there as well.</li>
<li><strong>Javascript</strong>. One of the reasons for integrating Dojo was to allow doing fun things like client-side validation; this allowed giving early feedback, without a round-trip to the server. But this also meant that we had validation logic duplicated between the server-side and client-side logic. And more interestingly: the form might be sent as a request <em>by javascript</em>, instead of a standard form request, which meant that we needed to validate it only, and then serialize validation status and messages. Basically, all the rendering aspects of the form were irrelevant in this scenario. Which brings me to...</li>
<li><strong>APIs.</strong> Around this time, APIs started trending. It would be a few years before REST became popular and commonly understood by developers, but folks were starting to see that we'd be needing them for the nascent mobile application markets, and that they were going to be a useful way to conduct business-to-business transactions. Once you start having APIs in the mix, a library centered on <em>web forms</em> becomes less interesting.</li>
</ul><p>By the time we started planning for version 2 of ZF, we realized we'd need to reconsider how we did forms. The first step we took was splitting the validation aspect from the form aspect, and created <code>Zend\InputFilter</code> to address the first, and <code>Zend\Form</code> to address the second. Input filters encapsulated how to filter, normalize, and validate incoming data. Forms composed an input filter, and then provided hints for the view layer to allow rendering the elements. This separation helped a fair bit: you could re-use input filters for handling API or JS requests easily, while the form layer helped with rendering HTML forms.</p><p>But I still feel we didn't get it right:</p><ul><li>Our validation component and our input filter component were each <em>stateful</em>. When you performed validation, each would store the values, validation status, and validation messages as part of the state. This makes re-use within the same request more difficult (it was not uncommon to use the same validator with multiple elements, and this now required multiple instances), makes testing more difficult, and makes it harder to understand if the instance represents the definition, or the results of validation.</li>
<li>The longer I've worked in web development, the more I've realized that while the HTML generation aspects of these form libraries are useful for prototyping, they inevitably cannot be used for the final production code. Designers, user experience experts, and accessibility developers will each want different features represented, and these will <em>never</em> fall into the defaults the framework provides. Even if the framework provides customization features, the end result is <em>more</em> programming effort. It's almost always better to code the HTML markup in your templates, and then feed state (e.g., element IDs/names, validation state, whether or not to display placeholders and/or error messages, etc.) from some object representing form or element state.</li>
</ul><p>A few years back, I started an RFC for Laminas to create an idempotent validation library, one that would not even consider web form integration, but never quite hit on a good design. What with my work role changing, and having more and more varied interests outside work, I essentially abandoned it.</p><h3>Uh oh, I did it again</h3><p>Until recently.</p><p>I develop a number of internal tools for work to support some of the different functional teams with whom I work. These often require validation at some point, with varying amounts of complexity. As such, I've used these tools as a way for me to play with some of these ideas around validation and forms.</p><p>In developing the last couple of tools, I found a pattern that was working. I decided to extract it, and then iterated on it some more. Each iteration, I'd update one of these applications to see how it worked, what it enabled, and what was getting in the way.</p><p>I came up with a few goals:</p><ul><li>Provide an idempotent way to validate individual items and/or data sets.</li>
<li>Provide an extensible framework for developing validation rules.</li>
<li>Allow handling optional data, with default values.</li>
<li>Allow reporting validation error messages.</li>
<li>Ensure missing required values are reported as validation failures.</li>
<li>Use as few dependencies as possible.</li>
</ul><p>I also came up with some explicit <em>non-goals</em>:</p><ul><li>Creating an extensive set of validation rule classes.</li>
<li>Providing extensive mechanisms for validating and returning nested data sets.</li>
<li>Providing a configuration-driven mechanism for creating rule sets.</li>
<li>Providing HTML form input representations or all metadata required to create HTML form input representations.</li>
</ul><p>What I wanted was something that could validate an incoming data set, return a validation result, and then use that result to report back to the user. In the case of an API, for an invalid result, I'd be able to get the validation error messages, which could then be used to seed a <a href="https://www.rfc-editor.org/rfc/rfc7807">Problem Details for HTTP APIs</a> message. In the case of a web form, I'd be able to extract values, validation status, and validation error messages.</p><p>One thing I realized early on was that it was also useful to be able to represent a form's <em>initial state</em>. This would allow using the same template for both the initial form, as well as reporting form validation errors later.</p><p>Finally, I wanted a solution that reported types and would play nicely with static analysis. If I'm pulling a result out of a result set, I want to know that the value <em>type</em> is what I expect it to be. This helps with testing, provides IDE hinting, and helps ensure I'm using the features correctly. I think I ended up spending more time on this aspect than anything.</p><p>The result is my <a href="https://github.com/phly/phly-rule-validation">phly/phly-rule-validation</a> library. I developed it for PHP 8.2 and up, as I wanted to use some specific features (though the ones specific to 8.2 and up... I ended up having to remove, so it would likely work on 8.0 or 8.1 as well). It's a little over 600 lines of code in total, and has no additional dependencies. It's also incredibly sparse; I only include 2 default validation rules.</p><p>The basic idea is:</p><ul><li>You create a <em>rule set</em>, consisting of <em>rules</em>.</li>
<li>A <em>rule</em> defines:
<ul><li>The <em>key</em> it maps to in the data set being validated.</li>
<li>A method for <em>validating</em> a value, which produces a <em>result</em>.</li>
<li>A way to produce <em>results</em> for each of a <em>default</em> value, and when the value is <em>missing</em>.</li>
</ul></li>
<li>Rule validation produces a <em>result</em>, which composes:
<ul><li>The <em>key</em> associated with the result.</li>
<li>The <em>value</em> associated with the result. The validation routine <em>can</em> normalize the result if desired, so this value might not be 1:1 with what was submitted. This approach allowed me to not require splitting filtering/normalization from validation, as it becomes an implementation detail.</li>
<li>The <em>validation state</em>: is it valid, or not?</li>
<li>The validation <em>message</em>: this will generally only be populated for <em>invalid</em> values, and representes a validation <em>error message</em>.</li>
</ul></li>
<li>A <em>rule set</em> produces a <em>result set</em>, which is a collection of <em>results</em>.</li>
</ul><p>In all cases, there are static analysis templates provided to allow defining the <em>types</em>. A validation result allows defining the <em>value type</em>, and a result set allows mapping keys to specific result types. Rules return result types. And so on.</p><p>A rule set can produce a <em>valid result set</em>, and this can be used to seed the initial state of a form. And I built support for <em>nested results</em>, which allows having forms that have groups of data.</p><p>The library provides usage examples, and I wrote <a href="https://github.com/phly/phly-rule-validation/tree/0.2.x/docs">quite a bit of documentation</a>, if you want to see how it works.</p><h3>Some thoughts</h3><p>Is the result perfect? Probably not. I know that folks used to things like ZF, Laminas, Symfony, or Laravel forms will likely dislike the approach, as it does not allow for quick prototyping of web forms. I don't find that to be a detriment, however; as I noted earlier, the final production version of a form is likely going to be created by a designer, and won't work well with the HTML generation aspects of these systems anyways. For folks who only want to validate API payloads, while it will be a nice, lightweight approach, it doesn't provide a lot of defaults. Again, that's by design, as it allows developers to customize their validation logic and, more importantly, test it independently.</p><p>I've updated some of my applications to use this library. In some cases, I had a net reduction of code. In others, I ended up with more, but a far clearer understanding of what's in a form, how each item is validated, and what types are expected. And since the bulk of phly-rule-validation is around interfaces, it means that I'm not concerned about <em>how the library works</em>; it's pretty clear how it <em>will</em> work just from viewing the classes I've created.</p><p>One benefit of creating the library is that it helped me better understand <a href="https://psalm.dev">Psalm</a> and type templates. There are definitely limitations, and some things produce WTF moments, but when it all comes together, it's kind of magical. In some forms I built, it was amazing to be in a view template and get completion for everything, along with an understanding of what various types were, and warnings when I was doing an operation that couldn't use the type for a given element.</p><p>And these are the reasons I developed the library. I wanted something explicit, idempotent, and static analysis friendly, as these would make testing and IDE integration more straight-forward. I think I succeeded in that goal.</p>]]></description>
      <link>https://mwop.net/blog/2023-12-09-advent-forms.html</link>
      <guid>https://mwop.net/blog/2023-12-09-advent-forms.html</guid>
      <pubDate>Sat, 09 Dec 2023 18:00:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[Cutting through the static - Larry Garfield]]></title>
      <description><![CDATA[<header><p>Submitted by Larry on 29 November 2023 - 4:28pm</p>
</header><div class="node__content clearfix"><div class="clearfix text-formatted field field--name-body field--type-text-with-summary field--label-hidden field__item"><p>Static methods and properties have a storied and controversial history in PHP. Some love them, some hate them, some love having something to fight about (naturally).</p><p>In practice, I find them useful in very narrow situations. They're not common, but they do exist. Today, I want to go over some guidelines on when PHP developers should, and shouldn't, use statics.</p><p>In full transparency, I will say that the views expressed here are not universal within the PHP community. They do, however, represent what I believe to be the substantial majority opinion, especially among those who are well-versed in automated testing.</p><p><em>Continue reading this post on <a href="https://peakd.com/hive-168588/@crell/cutting-through-the-static">PeakD</a>.</em></p></div><div class="field field--name-blog-topics field--type-entity-reference field--label-hidden field__items"><p><a href="https://www.garfieldtech.com/topics/web-development/php" hreflang="en">PHP</a></p><p><a href="https://www.garfieldtech.com/blog-topics/oop" hreflang="en">OOP</a></p></div></div>]]></description>
      <link>https://www.garfieldtech.com/blog/static-methods</link>
      <guid>https://www.garfieldtech.com/blog/static-methods</guid>
      <pubDate>Wed, 29 Nov 2023 23:28:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[Automating the backslash prefixing for native PHP function calls - Raphael Stolt]]></title>
      <description><![CDATA[<p>After reading the blog post <a href="https://www.deviaene.eu/articles/2023/why-prefix-php-functions-calls-with-backslash/" target="_blank">Why does a backslash prefix improve PHP function call performance</a> by Jeroen Deviaene I was looking for a way to automate it for the codebase of the <a href="https://github.com/raphaelstolt/lean-package-validator">Lean Package Validator</a>, to shave off some miliseconds for it's CLI. The PHP Coding Standards Fixer has a rule named <a href="https://cs.symfony.com/doc/rules/function_notation/native_function_invocation.html">native_function_invocation</a> which does the very exact task.<br /></p>
<h4 class="custom">Configuring the PHP Coding Standards Fixer</h4>
<div class="refactoringStatus c1">.php-cs-fixer.php</div>
<pre class="codeSnippetRefactoring">&lt;?php
use PhpCsFixer\Config;
use PhpCsFixer\Finder;
$finder = Finder::create()
    -&gt;in([__DIR__, __DIR__ . DIRECTORY_SEPARATOR . 'tests']);
$rules = [
    'psr_autoloading' =&gt; false,
    '@PSR2' =&gt; true,
    'phpdoc_order' =&gt; true,
    'ordered_imports' =&gt; true,
    <strong>'native_function_invocation' =&gt; [
        'include' =&gt; ['@internal'],
        'exclude' =&gt; ['file_put_contents']
    ]</strong>
];
$cacheDir = \getenv('HOME') ? \getenv('HOME') : __DIR__;
$config = new Config();
return $config-&gt;setRules($rules)
    -&gt;setFinder($finder)
    -&gt;setCacheFile($cacheDir . '/.php-cs-fixer.cache');
</pre>
To make this rule executeable I needed to add the <em class="ghl">--allow-risky=yes</em> option to the PHP Coding Standards Fixer calls in the two dedicated Composer scripts shown next.
<div class="refactoringStatus c2">composer.json</div>
<pre class="codeSnippetRefactoring">"scripts": {
    "lpv:test": "phpunit",
    "lpv:test-with-coverage": "export XDEBUG_MODE=coverage &amp;&amp; phpunit --coverage-html coverage-reports",
    <strong>"lpv:cs-fix": "php-cs-fixer --allow-risky=yes fix . -vv || true",
    "lpv:cs-lint": "php-cs-fixer fix --diff --stop-on-violation --verbose --dry-run --allow-risky=yes",</strong>
    "lpv:configure-commit-template": "git config --add commit.template .gitmessage",
    "lpv:application-version-guard": "php bin/application-version --verify-tag-match=bin",
    "lpv:application-phar-version-guard": "php bin/application-version --verify-tag-match=phar",
    "lpv:static-analyse": "phpstan analyse --configuration phpstan.neon.dist", 
    "lpv:validate-gitattributes": "bin/lean-package-validator validate"
},
</pre>
After running the <em class="ghl">lpv:cs-fix</em> Composer script the first time the test of the system under test started failing due to <em class="ghl">file_put_contents</em> being prefixed with a backslash, so I had to exclude it as shown in the PHP Coding Standards Fixer configuration above.]]></description>
      <link>http://raphaelstolt.blogspot.com/2023/11/automating-backslash-prefixing-for.html</link>
      <guid>http://raphaelstolt.blogspot.com/2023/11/automating-backslash-prefixing-for.html</guid>
      <pubDate>Thu, 23 Nov 2023 14:21:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[Using JSX on the server as a template engine - Evert Pot]]></title>
      <description><![CDATA[<p>The React/Next.js ecosystem is spinning out of control in terms of magic and complexity. The stack has failed to stay focused and simple, and it’s my belief that software stacks that are too complex and magical must eventually fail, because as sensibilities around software design change they will be unable to adapt to those changes without cannibalizing their existing userbase.</p><p>So while React/Next.js may be relegated to the enterprise and legacy systems in a few years, they completely transformed front-end development and created ripple effects in many other technologies. One of many great ideas stemming from this stack is <a href="https://en.wikipedia.org/wiki/JSX_(JavaScript)">JSX</a>. I think JSX has a chance to stay relevant and useful beyond React/Next.</p><p>One of it’s use-cases is for server-side templating. I’ve been using JSX as a template engine to replace template engines like <a href="https://ejs.co/">EJS</a> and <a href="https://handlebarsjs.com/">Handlebars</a>, and more than once people were surprised this was possible without bulky frameworks such as Next.js.</p><p>So in this article I’m digging into what JSX is, where it comes from and how one might go about using it as a simple server-side HTML template engine.</p><h2 id="what-is-jsx">What is JSX?</h2><p>JSX is an extension to the Javascript language, and was introduced with React. It usually has a <code class="language-plaintext highlighter-rouge">.jsx</code> extension and it needs to be compiled <em>to</em> Javascript. Most build tools people already use, like ESbuild, Babel, Vite, etc. all support this natively or through a plugin. Typescript also natively supports it, so if you use Typescript you can just start using it without adding another tool.</p><p>It looks like this:</p><div class="language-jsx highlighter-rouge highlight"><pre>const foo = &lt;div&gt;
  &lt;h1&gt;Hello world!&lt;/h1&gt;
  &lt;p&gt;Sup&lt;/p&gt;
&lt;/div&gt;;
</pre></div><p>As you can see here, some HTML is directly embedded into Javascript, without quotes. It’s all syntax. It lets you use the full power of Javascript, such as variables and loops:</p><div class="language-jsx highlighter-rouge highlight"><pre>const user = 'Evert';
const todos = [
  'Wash clothes',
  'Do dishes',
];
const foo = &lt;div&gt;
  &lt;h1&gt;Hello {evert}&lt;/div&gt;
  &lt;ul&gt;
    {todos.map( todo =&gt; &lt;li&gt;todo&lt;/li&gt;)}
  &lt;/ul&gt;
&lt;/div&gt;;
</pre></div><p>It has a convention to treat tags that start with a lowercase character such as <code class="language-plaintext highlighter-rouge">&lt;h1&gt;</code> as output, but if the tag starts with an uppercase character, it’s a component, which usually is represented by a function:</p><div class="language-jsx highlighter-rouge highlight"><pre>function HelloWorldComponent(props) {
  return &lt;h1&gt;Hello &lt;span&gt;{props.name}&lt;/span&gt;&lt;/h1&gt;
}
const foo = &lt;section&gt;
  &lt;HelloWorldComponent name="Evert" /&gt;
&lt;/section&gt;;
</pre></div><p>Anyway, if you’re reading this you likely knew most of this but it’s important to state that this are all JSX features, not React.</p><h2 id="inspo">#Inspo</h2><p>JSX probably has it’s roots in <a href="https://en.wikipedia.org/wiki/ECMAScript_for_XML">E4X</a> (and more directly <a href="https://docs.hhvm.com/hack/XHP/introduction">XHP</a>). E4X was a way to embed XML in Javascript. E4X has been supported in Firefox for years, and was a part of ActionScript 3 onwards, but there’s a major conceptual difference between E4X and JSX.</p><p>With E4X you embed XML documents as data, similar to defining a JSON object in a Javascript file. After defining the XML document you can manipulate it. A fictional transpiler for E4X could (as far as I can tell) could just take the XML structure and turn it into a string and pass it to <a href="https://developer.mozilla.org/en-US/docs/Web/API/DOMParser/parseFromString"><code class="language-plaintext highlighter-rouge">DOMParser.parseFromString()</code></a>. In E4X there are no variables, functions, components, or logic. Similar to how a Regular expression is part of the JS language.</p><p>JSX is quite different to this. It’s fully integrated in the language and it effectively compiles down to nested function definitions. These functions are don’t get turned into HTML until they are called by <a href="https://legacy.reactjs.org/docs/rendering-elements.html#rendering-an-element-into-the-dom" title="Rendering an Element into the DOM">some render function</a>. Before this they are defined but not evaluated.</p><p>So while E4X and JSX share that they both make XML/HTML first-class citizens in the language, the goals and features are wildly different. JSX really is a <a href="https://en.wikipedia.org/wiki/Domain-specific_language">DSL</a>.</p><h2 id="jsx-transpiled">JSX Transpiled</h2><p>Lets turn the previous example into Typescript, and see what Typescript does with it:</p><div class="language-jsx highlighter-rouge highlight"><pre>function HelloWorldComponent(props: { name: string }) {
  return &lt;h1&gt;Hello &lt;span&gt;{props.name}&lt;/span&gt;&lt;/h1&gt;
}
const foo = &lt;section&gt;
  &lt;HelloWorldComponent name="Evert" /&gt;
&lt;/section&gt;;
</pre></div><p>By default, Typescript will turn it into this:</p><div class="language-javascript highlighter-rouge highlight"><pre>function HelloWorldComponent(props) {
    return React.createElement("h1", null,
        "Hello ",
        React.createElement("span", null, props.name));
}
const foo = React.createElement("section", null,
    React.createElement(HelloWorldComponent, { name: "Evert" }));
</pre></div><p>Now, there’s definitely a react dependency here, but in recent versions of Typescript, we can configure it to use a different ‘factory’ for JSX. By setting the <a href="https://www.typescriptlang.org/tsconfig#jsx">jsx</a> and <a href="https://www.typescriptlang.org/tsconfig#jsxFactory">jsxFactory</a> settings in <code class="language-plaintext highlighter-rouge">tsconfig.json</code>, we can get Typescript to output more generic code:</p><div class="language-javascript highlighter-rouge highlight"><pre>function HelloWorldComponent(props) {
    return _jsxs("h1", { children: ["Hello ", _jsx("span", { children: props.name })] });
}
const foo = _jsx("section", { children: _jsx(HelloWorldComponent, { name: "Evert" }) });
</pre></div><p>So what’s <code class="language-plaintext highlighter-rouge">_jsx</code>? This is a ‘jsx factory’ function that can be provided by React, but also a number of other libraries such as <a href="https://preactjs.com/">Preact</a> or <a href="https://www.solidjs.com/">Solid.js</a>. It’s also relatively easy to <a href="https://lwebapp.com/en/post/custom-jsx" title="Custom JSX Factory Function">create your own</a>.</p><p>What’s interesting then about JSX is that while it’s syntax, it’s not always clear what this yields:</p><div class="language-javascript highlighter-rouge highlight"><pre>const foo = &lt;h1&gt;Sup!&lt;/h1&gt;
</pre></div><p>Because what’s in <code class="language-plaintext highlighter-rouge">foo</code> depends on what JSX Factory was used during transpiling. This is frustrating because it requires out of band information and external configuration, but also a benefit because it opens the doors to alternative implementations.</p><h2 id="using-jsx-as-a-template-engine">Using JSX as a template engine</h2><p>When generating HTML on the server with Node, it’s pretty common to use template engines such as <a href="https://ejs.co/">EJS</a> or <a href="https://handlebarsjs.com/">Handlebars</a>. When building a new (multi-page) web application, it occurred to me that neither are quit as good as JSX.</p><p>Some of the advantages of JSX are:</p><ul><li>Deep IDE/Language server/intellisense integration, because it’s all syntax.</li>
<li>Static type checking with Typescript.</li>
<li>It also enforced correctly structured HTML. No way to forget to close an element.</li>
<li>By default dynamic data is escaped. They made it challenging to get unescaped HTML!</li>
</ul><p>This had me wondering, can we use server-side microframeworks such as <a href="https://koajs.com/">Koa</a>, <a href="https://fastify.dev/">Fastify</a> or <a href="https://expressjs.com/">Express</a> but instead of string-based template parsers and get all the benefits of JSX?</p><p>Turns out the answer is, yes! It’s not only pretty simple to implement, it works exceedingly well.</p><p>I’ve implemented this pattern 3 times now for different frameworks, here’s some sample code that works:</p><h3 id="koa">Koa</h3><p>Here’s an example of a small controller:</p><div class="language-tsx highlighter-rouge highlight"><pre>import Router from 'koa-router';
const router = new Router();
router.get('/foo.html', ctx =&gt; {
  ctx.response.body = &lt;h1&gt;Hello world with JSX in Koa!&lt;/h1&gt;;
});
</pre></div><p>As you can see here we can set JSX straight on the body property. A middleware ensures this gets transformed into HTML.</p><h3 id="fastify">Fastify</h3><p>Similar to Koa, we can use JSX instead where otherwise HTML strings would be used:</p><div class="language-tsx highlighter-rouge highlight"><pre>import { FastifyInstance } from 'fastify'
export function routes(fastify: FastifyInstance) {
  fastify.get('/hello-world', request =&gt; &lt;h1&gt;Sup Fastify!&lt;/h1&gt;);
}
</pre></div><h2 id="how-does-this-magic-work">How does this magic work?</h2><p>For both of these I used the React library. Despite it’s ecosystem being rather bulky, standalone React is still pretty lean and highly optimized.</p><p>For both of these frameworks, I simply created a middleware that checks if the body is a React node, and if so use React’s <a href="https://react.dev/reference/react-dom/server/renderToStaticMarkup">renderToStaticMarkup</a> to do the transformation before the response is sent.</p><h3 id="koa-middleware">Koa middleware</h3><div class="language-tsx highlighter-rouge highlight"><pre>import { renderToStaticMarkup } from 'react-dom/server';
import { isValidElement } from 'react';
import { Context, Middleware, Next } from 'koa';
export const jsx: Middleware = async(ctx: Context, next: Next) =&gt; {
  await next();
  if (isValidElement(ctx.response.body)) {
    ctx.response.body = '&lt;!DOCTYPE html&gt;\n' + renderToStaticMarkup(
      ctx.response.body
    );
    ctx.response.type = 'text/html; charset=utf-8';
  }
};
</pre></div><p>This is how it’s used:</p><div class="language-tsx highlighter-rouge highlight"><pre>const application = new Koa();
application.use(jsx);
</pre></div><h3 id="fastify-hooks">Fastify hooks</h3><p>This one needed a few more hacks, but the result is worth it:</p><div class="language-tsx highlighter-rouge highlight"><pre>import { onSendHookHandler, preSerializationHookHandler } from 'fastify';
import { isValidElement } from 'react';
import { renderToStaticMarkup } from 'react-dom/server';
/**
 * The preserialization hook lets us transform the response body
 * before it's json-encoded.
 *
 * We use this to turn React components into an object with a ___jsx key
 * that has the serialized HTML.
 */
export const preSerialization: preSerializationHookHandler&lt;unknown&gt; = async (_request, reply, payload: unknown) =&gt; {
  if (isValidElement(payload)) {
    reply.header('Content-Type', 'text/html');
    return {
      ___jsx: '&lt;!DOCTYPE html&gt;\n' + renderToStaticMarkup(payload as any)
    };
  } else {
    return payload;
  }
};
/**
 * The onSendHookHandler lets us transform the response body (as a string)
 * We detect the ___jsx key and unwrap the HTML.
 */
export const onSend: onSendHookHandler&lt;unknown&gt; = async (_request, _reply, payload: unknown) =&gt; {
  if (typeof payload==='string' &amp;&amp; payload.startsWith('{"___jsx":"')) {
    return JSON.parse(payload).___jsx;
  }
  return payload;
};
</pre></div><p>To use the hook:</p><div class="language-typescript highlighter-rouge highlight"><pre>const fastify = Fastify();
// These 2 hooks allow us to render React/jsx tags straight to HTML
fastify.addHook('preSerialization', jsxRender.preSerialization);
fastify.addHook('onSend', jsxRender.onSend);
</pre></div><p>Using Preact or your own factory should also totally work here.</p><h2 id="limitations-to-this-approach">Limitations to this approach</h2><p>Users of React and other frameworks may be used to pulling in data asynchronously and updating their document. This approach only allows for a single pass, so this means that all dynamic data to your JSX templates needs to be fetched in advance and passed down as props.</p><p>This means no hooks or state.</p><p>To me this is an advantage because the paradigm it replaces is regular templates, and with those the data is typically also passed in ‘at the top’.</p><p>It would certainly be possible to implement Suspend and allow for asynchronous data fetching or wait for other signals, but I haven’t yet needed this.</p><h2 id="frequently-asked-questions">Frequently asked questions</h2><h3 id="how-do-you-handle-routing">How do you handle routing?</h3><p>The short answer is: you don’t. Routing is already handled by your framework, and each route/endpoint/controller is responsible for rendering it’s entire page.</p><p>To reuse things like the global layout, you use components. A slightly fictionalized example of a page for us looks like this:</p><div class="language-tsx highlighter-rouge highlight"><pre>ctx.body = &lt;PublicLayout&gt;
  &lt;div&gt;
    &lt;h1&gt;Welcome back!&lt;/h1&gt;
  &lt;/div&gt;
  &lt;form method="post" action="/login"&gt;
    &lt;label&gt;
      &lt;span&gt;Email&lt;/span&gt;
      &lt;input type="email" name="email" required minLength={10} /&gt;
    &lt;/label&gt;
    &lt;label&gt;
      &lt;span&gt;Password&lt;/span&gt;
      &lt;input type="password" name="password" required minLength={4} /&gt;
    &lt;/label&gt;
    &lt;button type="submit"&gt;Log In&lt;/button&gt;
  &lt;/form&gt;
&lt;/PublicLayout&gt;;
</pre></div><p>This in effect ‘inherits’ from <code class="language-plaintext highlighter-rouge">PublicLayout</code>, which looks like this:</p><div class="language-tsx highlighter-rouge highlight"><pre>type Props = {
  children: JSX.Element[]|JSX.Element;
  className: string;
}
/**
 * This is the main application wrapper, shared by all HTML pages.
 */
export function PublicLayout(props: Props) {
  return &lt;html&gt;
    &lt;head&gt;
      &lt;title&gt;Sprout Family&lt;/title&gt;
      &lt;link href="/css/main.css" rel="stylesheet" type="text/css" /&gt;
      &lt;meta name="viewport" content="width=device-width, initial-scale=1" /&gt;
      &lt;script src="/js/utils.js"&gt;&lt;/script&gt;
    &lt;/head&gt;
    &lt;body className={props.className}&gt;
      { props.children }
    &lt;/body&gt;
  &lt;/html&gt;;
}
</pre></div><h3 id="is-there-still-a-reason-to-use-handlebars-or-ejs">Is there still a reason to use Handlebars or EJS?</h3><p>I think one benefit of these template languages are they they are their own isolated format with limited capabilities.</p><p>This is helpful when for example you build an application and let your own users edit templates. Perhaps you for example have a ‘welcome email’ and want to let your users/tenants modify it.</p><p>Giving them the full power of a Javascript + a DSL that needs to be transpiled might be a negative here, because limiting features makes it easier to evolve systems and there’s also a major security component.</p><p>My template engine of choice for these is probably <a href="https://handlebarsjs.com/">handlebars</a> or even the more limited variant <a href="https://mustache.github.io/">mustache</a>.</p><h2 id="anyway">Anyway</h2><p>Hope this was interesting. If there’s interest in turning my Koa and Fastify code into real NPM packages, let me know! Happy to do it if there’s a non-0 number of users.</p><p>In the future I might even be interested in developing my own JSX Factory that allows awaiting for async components.</p><p>If any of this sounds interesting, you have a scathing critique or found punctuation in the wrong place, you can leave a comment by replying to this <a href="https://indieweb.social/@evert/111409207581858234">Mastodon post</a>.</p>]]></description>
      <link>https://evertpot.com/jsx-template/</link>
      <guid>https://evertpot.com/jsx-template/</guid>
      <pubDate>Tue, 14 Nov 2023 14:14:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[Announcing Crell/Serde 1.0.0 - Larry Garfield]]></title>
      <description><![CDATA[<header><p>Submitted by Larry on 9 November 2023 - 7:39pm</p>
</header><div class="node__content clearfix"><div class="clearfix text-formatted field field--name-body field--type-text-with-summary field--label-hidden field__item"><p>I am pleased to announce that the trio of libraries I built while at <a rel="noopener noreferrer" target="_blank" href="https://typo3.com/">TYPO3</a> have now reached a fully stable release. In particular, <a rel="noopener noreferrer" target="_blank" href="http://github.com/Crell/Serde">Crell/Serde</a> is now the most robust, powerful, and performant serialization library available for PHP today!</p><p>Serde is inspired by the Rust library of the same name, and driven almost entirely by PHP Attributes, with entirely pure-function object-oriented code. It's easy to configure, easy to use, and rock solid.</p><p>For a full overview, I gave a <a rel="noopener noreferrer" target="_blank" href="https://www.youtube.com/watch?v=GB5Vfi68ToY">presentation</a> at <a rel="noopener noreferrer" target="_blank" href="https://www.longhornphp.com/">Longhorn PHP 2023</a> that went into its capabilities in detail. Even then, I didn't have time to cover everything! Have a look at the README for a complete list of all the options and features available.</p><p>Serde is backed by two other libraries:</p><ul><li><a rel="noopener noreferrer" target="_blank" href="http://github.com/Crell/fp">Crell/fp</a> is a simple functional programming utility library, mainly aimed at enabling functional pipes.</li>
<li><a rel="noopener noreferrer" target="_blank" href="http://github.com/Crell/AttributeUtils">Crell/AttributeUtils</a> is a fully-featured attribute management library that builds on PHP's native attributes and adds a metric ton of functionality. A lot of the functionality of Serde is driven directly by AttributeUtils.</li>
</ul><p>Give all three a try, and see how powerful modern PHP has become!</p></div><div class="field field--name-blog-topics field--type-entity-reference field--label-hidden field__items"><p><a href="https://www.garfieldtech.com/topics/web-development/php" hreflang="en">PHP</a></p><p><a href="https://www.garfieldtech.com/taxonomy/term/125" hreflang="en">Serialization</a></p><p><a href="https://www.garfieldtech.com/taxonomy/term/134" hreflang="en">Serde</a></p><p><a href="https://www.garfieldtech.com/topics/web-development" hreflang="en">Web development</a></p></div></div>]]></description>
      <link>https://www.garfieldtech.com/blog/serde-release</link>
      <guid>https://www.garfieldtech.com/blog/serde-release</guid>
      <pubDate>Fri, 10 Nov 2023 02:39:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[Xdebug Update: October 2023 - Derick Rethans]]></title>
      <description><![CDATA[<p>In this monthly update I explain what happened with Xdebug development in the past month. These are normally published on the first Tuesday on or after the 5th of each month.</p><p><a href="https://www.patreon.com/derickr">Patreon</a> and <a href="https://github.com/sponsors/derickr/">GitHub</a> supporters will get it earlier, around the first of each month.</p><p>You can <a href="https://www.patreon.com/bePatron?u=7864328">become a patron</a> or support me through <a href="https://github.com/sponsors/derickr">GitHub Sponsors</a>. I am currently 35% towards my $2,500 per month goal, which is set to allow continued maintenance of Xdebug.</p><p>If you are leading a team or company, then it is also possible to support Xdebug through <a href="https://xdebug.org/support">a subscription</a>.</p><p>In the last month, I spend around 32 hours on Xdebug, with 25 hours funded.</p><div class="articleSubSection"><h2>Towards Xdebug 3.3</h2><p>In <a href="https://derickrethans.nl/xdebug-update-september-2023.html#towards_xdebug_3_3">last month's update</a> I explained that I was investigating whether Xdebug can make use of PHP's Observer API. It turns out that it can be used to intercept function calls, but only <code>include</code> or <code>require</code> calls if the included files contain code, and not just class definitions. As Xdebug treats <code>include</code> and friends as actual function calls, I can unfortunately not solely rely on the Observer API.</p><p>In the wake of checking out the Observer API, I also thought I should have a look at some performance improvements. For example, I noticed that Xdebug would always collect local variables with each function call. This is only really needed when showing local variables, in stack traces, or through the step debugger.</p><p>Another optimisation that I worked on was to optimise the way how function breakpoints are checked against. These breakpoints trigger when a function gets called, or returned from. This is not a feature that many people often use, but Xdebug would always do some work to be able to compare the configured breakpoints against a normalised function name reference.</p><p>These two optimisations together resulted in a 20% reduction in CPU instructions (roughly equivalent to execution time) with the front page of WordPress' demo site.</p><p>The third optimisation that I worked is related to file/line breakpoints. Xdebug would evaluate whether an IDE has set a line breakpoint on the current line. For this, it had to loop over all the existing breakpoints and compare them. Each additional breakpoint would be checked after every statement, meaning that the number of breakpoints affected the running time of the script.</p><p>My optimisation alleviates this by moving the check on whether line breakpoints exist for a function or method to the function call itself. If no breakpoints are set in the whole function, then Xdebug skips the check for line breakpoints after each statement. This shifts the factor of performance loss for having line breakpoints from the <strong>number of statements</strong> to the <strong>number of function calls</strong>. This shift results in a roughly 25% performance boost with only four line breakpoints enabled.</p><p>After attending IPC and speaking to fellow Xdebug users, a question came up about long running scripts. Right now, Xdebug's step debugger can only be activated when the script starts or by calling <a href="https://xdebug.org/docs/all_functions#xdebug_connect_to_client">xdebug_connect_to_client()</a>. Breakpoints can also only be configured when Xdebug is waiting for a command to continue a script (after a step, an existing breakpoint, or at the start of the script). While a script is running, you can not interrupt the execution to break, or add new breakpoints.</p><p>This let me to experiment with a control socket, currently only available on Linux. Through this socket you can then ask Xdebug for information, or request a breakpoint so that you can then use your IDE to add more breakpoints, or inspect the current state.</p><p>At the moment, I have implemented the "show me some information" feature, which allows me to show the running PHP scripts, with PID, memory usage (in kb), running time, and Xdebug version. The <code>xdebug</code> command line tool allows you to control Xdebug through the socket:</p><p>I have not merged this feature yet, but I hope to do so once I have the step debugger interruption feature as well.</p><p>Beyond this, I will continue to work on the features and issues on the <a href="https://bugs.xdebug.org/roadmap_page.php?version_id=101">3.3 roadmap</a>, without any guarantees these tickets will be implemented.</p></div><div class="articleSubSection"><h2>Xdebug Videos</h2><p>I have not published any new videos in the last month, but I did record one. It is set to premiere on November 7th. To get notified, you can subscribe to my <a href="https://www.youtube.com/playlist?list=PLg9Kjjye-m1g_eXpdaifUqLqALLqZqKd4">YouTube channel</a>, or follow <a href="https://phpc.social/@derickr">me</a> or <a href="https://phpc.social/@Xdebug">Xdebug</a> on Mastodon.</p></div><div class="articleSubSection"><h2>Business Supporter Scheme and Funding</h2><p>In the last month, no new business supporters signed up.</p><p>Besides business support, I also maintain a <a href="https://www.patreon.com/derickr">Patreon</a> page, a profile on <a href="https://github.com/sponsors/derickr">GitHub sponsors</a>, as well as an <a href="https://opencollective.com/xdebug">OpenCollective</a> organisation.</p></div><div class="articleSubSection"><h2>Xdebug Cloud</h2><p>Xdebug Cloud is the <em>Proxy As A Service</em> platform to allow for debugging in more scenarios, where it is hard, or impossible, to have Xdebug make a connection to the IDE. It is continuing to operate as Beta release.</p><p>Packages start at £49/month, and I have recently introduced a package for larger companies. This has a larger initial set of tokens, and discounted extra tokens.</p><p>If you want to be kept up to date with Xdebug Cloud, please sign up to the <a href="https://xdebug.cloud/newsletter">mailinglist</a>, which I will use to send out an update not more than once a month.</p></div>]]></description>
      <link>https://derickrethans.nl/xdebug-update-october-2023.html</link>
      <guid>https://derickrethans.nl/xdebug-update-october-2023.html</guid>
      <pubDate>Thu, 09 Nov 2023 16:00:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[PHP 8.3.0 RC 6 available for testing - PHP: Hypertext Preprocessor]]></title>
      <description><![CDATA[<div id="intro" class="clearfix container hero"><img class="hero-logo" src="https://www.php.net/images/logos/php-logo-white.svg" alt="php" width="240" height="120" /><p class="hero-text">A <strong>popular general-purpose scripting language</strong> that is especially suited to web development.<br />Fast, flexible and pragmatic, PHP powers everything from your blog to the most popular websites in the world.</p><p><a href="https://www.php.net/releases/8.2/index.php" class="hero-btn hero-btn-primary">What's new in 8.2</a> <a href="https://www.php.net/downloads.php" class="hero-btn hero-btn-secondary">Download</a></p><ul class="hero-versions"><li class="hero-version"><a class="hero-version-link" href="https://www.php.net/downloads.php#v8.2.12">8.2.12</a> · <a class="notes" href="https://www.php.net/ChangeLog-8.php#8.2.12">Changelog</a> · <a class="notes" href="https://www.php.net/migration82">Upgrading</a></li>
<li class="hero-version"><a class="hero-version-link" href="https://www.php.net/downloads.php#v8.1.25">8.1.25</a> · <a class="notes" href="https://www.php.net/ChangeLog-8.php#8.1.25">Changelog</a> · <a class="notes" href="https://www.php.net/migration81">Upgrading</a></li>
<li class="hero-version"><a class="hero-version-link" href="https://www.php.net/downloads.php#v8.0.30">8.0.30</a> · <a class="notes" href="https://www.php.net/ChangeLog-8.php#8.0.30">Changelog</a> · <a class="notes" href="https://www.php.net/migration80">Upgrading</a></li>
</ul></div><div id="layout" class="clearfix"><section id="layout-content"><div class="home-content"><article class="newsentry"><header class="title"><time datetime="2023-11-09T09:33:47-08:00">09 Nov 2023</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the release of PHP 8.3.0, RC 6. This is the sixth and final release candidate, continuing the PHP 8.3 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php83">PHP Wiki</a>.</p><p>For source downloads of PHP 8.3.0, RC 6 please visit the <a href="https://downloads.php.net/~eric">download page</a>.</p><p>Please carefully test this version and report any issues found in the <a href="http://bugs.php.net">bug reporting system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.3.0RC6/NEWS">NEWS</a> file or the <a href="https://github.com/php/php-src/blob/php-8.3.0RC6/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be the production-ready, general availability release, planned for 23 November 2023.</p><p>The signatures for the release can be found in <a href="https://gist.github.com/ericmann/ceaadbc09bdbb49efb74212a6c8cf02a">the manifest</a> or on <a href="https://qa.php.net/">the QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-10-26T23:49:55+00:00">26 Oct 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.1.25. This is a bug fix release.</p><p>All PHP 8.1 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.1.25 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.1.25">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-10-26T16:39:13+00:00">26 Oct 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.12. This is a bug fix release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.12 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.12">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-10-26T15:00:24+00:00">26 Oct 2023</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the release of PHP 8.3.0, RC 5. This is the fifth release candidate, continuing the PHP 8.3 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php83">PHP Wiki</a>.</p><p>For source downloads of PHP 8.3.0, RC 5 please visit the <a href="https://downloads.php.net/~jakub/">download page</a>.</p><p>Please carefully test this version and report any issues found in the <a href="https://github.com/php/php-src/issues">bug reporting system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.3.0RC5/NEWS">NEWS</a> file or the <a href="https://github.com/php/php-src/blob/php-8.3.0RC5/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be the fourth release candidate (RC 5), planned for 26 October 2023.</p><p>The signatures for the release can be found in <a href="https://gist.github.com/bukka/c11ab353c69443c482219515838ed15a">the manifest</a> or on <a href="https://qa.php.net/">the QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-10-12T07:45:43-07:00">12 Oct 2023</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the release of PHP 8.3.0, RC 4. This is the fourth release candidate, continuing the PHP 8.3 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php83">PHP Wiki</a>.</p><p>For source downloads of PHP 8.3.0, RC 4 please visit the <a href="https://downloads.php.net/~eric/">download page</a>.</p><p>Please carefully test this version and report any issues found in the <a href="https://github.com/php/php-src/issues">bug reporting system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.3.0RC4/NEWS">NEWS</a> file or the <a href="https://github.com/php/php-src/blob/php-8.3.0RC4/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be the fifth release candidate (RC 5), planned for 26 October 2023.</p><p>The signatures for the release can be found in <a href="https://gist.github.com/ericmann/5531915317a5186bb4359bdd6c10e299">the manifest</a> or on <a href="https://qa.php.net/">the QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-09-28T18:04:30+00:00">28 Sep 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.1.24. This is a bug fix release.</p><p>All PHP 8.1 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.1.24 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.1.24">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-09-28T15:52:06+00:00">28 Sep 2023</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the release of PHP 8.3.0, RC 3. This is the third release candidate, continuing the PHP 8.3 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php83">PHP Wiki</a>.</p><p>For source downloads of PHP 8.3.0, RC 3 please visit the <a href="https://downloads.php.net/~jakub/">download page</a>.</p><p>Please carefully test this version and report any issues found in the <a href="https://github.com/php/php-src/issues">bug reporting system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.3.0RC3/NEWS">NEWS</a> file or the <a href="https://github.com/php/php-src/blob/php-8.3.0RC3/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be the fourth release candidate (RC 4), planned for 12 October 2023.</p><p>The signatures for the release can be found in <a href="https://gist.github.com/bukka/20e2e90e1ef16eb24c333f375203292e">the manifest</a> or on <a href="https://qa.php.net/">the QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-09-28T14:31:39+00:00">28 Sep 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.11. This is a bug fix release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.11 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.11">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-09-14T03:51:40-07:00">14 Sep 2023</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the release of PHP 8.3.0, RC 2. This is the second release candidate, continuing the PHP 8.3 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php83">PHP Wiki</a>.</p><p>For source downloads of PHP 8.3.0, RC 2 please visit the <a href="https://downloads.php.net/~eric/">download page</a>.</p><p>Please carefully test this version and report any issues found in the <a href="http://bugs.php.net">bug reporting system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.3.0RC2/NEWS">NEWS</a> file or the <a href="https://github.com/php/php-src/blob/php-8.3.0RC2/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be the third release candidate (RC 3), planned for 28 September 2023.</p><p>The signatures for the release can be found in <a href="https://gist.github.com/ericmann/d8c56e1244679ab41672dcfdbea2b0a6">the manifest</a> or on <a href="https://qa.php.net/">the QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-08-31T16:37:56+00:00">31 Aug 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.1.23. This is a bug fix release.</p><p>All PHP 8.1 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.1.23 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.1.23">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-08-31T16:15:39+00:00">31 Aug 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.10. This is a bug fix release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.10 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.10">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-08-31T11:23:53+00:00">31 Aug 2023</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the release of PHP 8.3.0, RC 1. This is the first release candidate, continuing the PHP 8.3 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php83">PHP Wiki</a>.</p><p>For source downloads of PHP 8.3.0, RC 1 please visit the <a href="https://downloads.php.net/~jakub/">download page</a>.</p><p>Please carefully test this version and report any issues found in the <a href="http://bugs.php.net">bug reporting system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.3.0RC1/NEWS">NEWS</a> file or the <a href="https://github.com/php/php-src/blob/php-8.3.0RC1/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be the second release candidate (RC 2), planned for 14 September 2023.</p><p>The signatures for the release can be found in <a href="https://gist.github.com/bukka/b5d4f8f27d1f013837e1f596d90ea1fc">the manifest</a> or on <a href="https://qa.php.net/">the QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-08-17T07:26:35-07:00">17 Aug 2023</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the third beta release of PHP 8.3.0, Beta 3. This continues the PHP 8.3 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php83">PHP Wiki</a>.</p><p>For source downloads of PHP 8.3.0 Beta 3 please visit the <a href="https://downloads.php.net/~eric">download page</a>.</p><p>Please carefully test this version and report any issues found in the <a href="https://github.com/php/php-src/issues">bug reporting system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.3.0beta3/NEWS">NEWS</a> file, or the <a href="https://github.com/php/php-src/blob/php-8.3.0beta3/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be RC 1, planned for Aug 31 2023.</p><p>The signatures for the release can be found in <a href="https://gist.github.com/ericmann/8ea0c14efef9b0e0a7e4222e06ed5097">the manifest</a> or on <a href="https://qa.php.net/">the QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-08-16T18:06:57+00:00">16 Aug 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.9. This is a security release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p><strong>Windows source and binaries are not synchronized and do not contain a fix for GH-11854.</strong></p><p>For source downloads of PHP 8.2.9 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.9">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-08-04T18:29:29+00:00">04 Aug 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.0.30. This is a security release.</p><p>All PHP 8.0 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.0.30 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.0.30">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-08-03T11:50:26-07:00">03 Aug 2023</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the second beta release of PHP 8.3.0, Beta 2. This continues the PHP 8.3 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php83">PHP Wiki</a>.</p><p>For source downloads of PHP 8.3.0 Beta 2 please visit the <a href="https://downloads.php.net/~jakub">download page</a>.</p><p>Please carefully test this version and report any issues found in the <a href="https://github.com/php/php-src/issues">bug reporting system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.3.0beta2/NEWS">NEWS</a> file, or the <a href="https://github.com/php/php-src/blob/php-8.3.0beta2/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be Beta 3, planned for Aug 17 2023.</p><p>The signatures for the release can be found in <a href="https://gist.github.com/bukka/31646ada5b94b4d2b78e0551905f5745">the manifest</a> or on <a href="https://qa.php.net/">the QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-08-03T15:07:49+00:00">03 Aug 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.1.22. This is a security release.</p><p>All PHP 8.1 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.1.22 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.1.22">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-07-20T08:11:32-07:00">20 Jul 2023</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the first beta release of PHP 8.3.0, Beta 1. This continues the PHP 8.3 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php83">PHP Wiki</a>.</p><p>For source downloads of PHP 8.3.0 Beta 1 please visit the <a href="https://downloads.php.net/~eric">download page</a>.</p><p>Please carefully test this version and report any issues found in the <a href="https://github.com/php/php-src/issues">bug reporting system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.3.0beta1/NEWS">NEWS</a> file, or the <a href="https://github.com/php/php-src/blob/php-8.3.0beta1/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be Beta 2, planned for Aug 3 2023.</p><p>The signatures for the release can be found in <a href="https://gist.github.com/ericmann/5d3b2ddc1c8696510614d81690d4b347">the manifest</a> or on <a href="https://qa.php.net/">the QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-07-06T14:45:21+00:00">06 Jul 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.1.21. This is a bug fix release.</p><p>All PHP 8.1 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.1.21 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.1.21">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-07-06T09:47:01+00:00">06 Jul 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.8. This is a bug fix release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.8 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.8">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-07-06T09:43:06+00:00">06 Jul 2023</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the third testing release of PHP 8.3.0, Alpha 3. This continues the PHP 8.3 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php83">PHP Wiki</a>.</p><p>For source downloads of PHP 8.3.0 Alpha 3 please visit the <a href="https://downloads.php.net/~jakub/">download page</a>.</p><p>Please carefully test this version and report any issues found in the <a href="https://github.com/php/php-src/issues">bug reporting system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.3.0alpha3/NEWS">NEWS</a> file, or the <a href="https://github.com/php/php-src/blob/php-8.3.0alpha3/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be Beta 1, planned for 20 Jul 2023.</p><p>The signatures for the release can be found in the <a href="https://gist.github.com/bukka/9324ba069ce9588c5000a60fbb8cccbb">manifest</a> or on the <a href="https://qa.php.net/">QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-06-22T11:15:33-07:00">22 Jun 2023</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the second testing release of PHP 8.3.0, Alpha 2. This continues the PHP 8.3 release cycle, the rouch outline of which is specified in the <a href="https://wiki.php.net/todo/php83">PHP Wiki</a>.</p><p>For source downloads of PHP 8.3.0 Alpha 2 please visit <a href="https://downloads.php.net/~eric/">download page</a>.</p><p>Please carefully test this version and report any issues found in the <a href="https://github.com/php/php-src/issues">bug reporting system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.3.0alpha2/NEWS">NEWS</a> file, or the <a href="https://github.com/php/php-src/blob/php-8.3.0alpha2/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be Alpha 3, planned for 6 July 2023.</p><p>The signatures for this release can be found in <a href="https://gist.github.com/ericmann/7355303dbb2d350522b155349c61fc7c">the manifest</a> or on <a href="https://qa.php.net/">the QA site</a>.</p><p>Thank you for helping us make PHP better!</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-06-08T18:24:16+00:00">08 Jun 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.1.20. This is a security release.</p><p>All PHP 8.1 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.1.20 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.1.20">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-06-08T18:14:14+00:00">08 Jun 2023</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the first testing release of PHP 8.3.0, Alpha 1. This starts the PHP 8.3 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php83">PHP Wiki</a>.</p><p>For source downloads of PHP 8.3.0 Alpha 1 please visit the <a href="https://downloads.php.net/~jakub/">download page</a>.</p><p>Please carefully test this version and report any issues found using <a href="https://github.com/php/php-src/issues">the bug tracking system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.3.0alpha1/NEWS">NEWS</a> file, or the <a href="https://github.com/php/php-src/blob/php-8.3.0alpha1/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be Alpha 2, planned for 22 Jun 2023.</p><p>The signatures for the release can be found in the <a href="https://gist.github.com/bukka/66530718f180092527a741d023492b23">manifest</a> or on the <a href="https://qa.php.net/">QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-06-08T16:50:22+00:00">08 Jun 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.7. This is a security release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.7 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.7">ChangeLog</a>.</p></div></article></div></section><aside class="tips"><div class="inner"><p class="panel"><a href="https://www.php.net/cal.php">User Group Events</a></p><p class="panel"><a href="https://www.php.net/thanks.php">Special Thanks</a></p></div>
</aside></div>]]></description>
      <link>https://www.php.net/index.php#2023-11-09-1</link>
      <guid>https://www.php.net/index.php#2023-11-09-1</guid>
      <pubDate>Thu, 09 Nov 2023 01:00:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[Flamboyant Flamegraphs - Derick Rethans]]></title>
      <description><![CDATA[<p>In this article, I am showing you how to make a flamegraph, a new feature in Xdebug 3.3.</p><p>Flamegraphs are an interesting way of showing where an application spends a lot of time.</p><p>To show you the functionality, I will be using Xdebug's own website, which I run locally at port 9874.</p><p>First of all, we need to configure Xdebug to make our flamegraphs. We do that in a configuration file. With <code>php --ini</code> I find out which file to use:</p><pre>Configuration File (php.ini) Path: /usr/local/php/8.2dev/lib
Loaded Configuration File:         /usr/local/php/8.2dev/lib/php.ini
Scan for additional .ini files in: /usr/local/php/8.2dev/lib/conf.d
Additional .ini files parsed:      /usr/local/php/8.2dev/lib/conf.d/20-mongodb.ini,
/usr/local/php/8.2dev/lib/conf.d/zzz-xdebug.ini
</pre><p>If you are running Apache or Nginx, I would suggest you use <code>phpinfo()</code> output in the browser to find the same information instead.</p><p>I have a specific Xdebug INI file called <code>zzz-xdebug.ini</code>. Its contents are currently:</p><pre>zend_extension=xdebug.so
xdebug.mode=develop,debug
</pre><p>Flamegraphs are part of Xdebug's tracing functionality, which we need to enable by changing the <code>xdebug.mode</code> line to:</p><pre>xdebug.mode=develop,debug,trace
</pre><p>The tracing functionality supports multiple formats. The flamegraph is number three, so we need to set that as well by adding:</p><pre>xdebug.trace_format=3
</pre><p>By default, Xdebug Tracer will put files into the <code>/tmp</code> directory, and use a hash of the current working directory to create a trace file name. We want distinct flamegraphs for each URL, so we need to change that by setting:</p><pre>xdebug.trace_output_name=xdebug.%R
</pre><p>We start all files with <code>trace.</code>, and then we use <code>%R</code> to configure to use the URI. Xdebug also supports many other <a href="https://xdebug.org/docs/trace#trace_output_name">formatting specifiers</a>.</p><p>By default, all file names will also be postfixed by <code>.xt.gz</code>.</p><p>After making INI changes, you need to restart the web server.</p><p>To initiate the tracer, I use an <a href="https://xdebug.org/docs/step_debug#browser-extensions">Xdebug Helper</a> browser extension available for Chrome, Firefox, and other browsers.</p><p>I click on the debug icon and then on trace:</p><p>After requesting the home page, and documentation page, Xdebug's tracer created the following files in the <code>/tmp</code> directory:</p><pre>derick@gargleblaster:~$ ls -l /tmp/trace.*
-rw-r--r-- 1 derick derick  123 Sep 26 03:31 /tmp/trace..05d7ef.xt.gz
-rw-r--r-- 1 derick derick 2560 Sep 25 16:55 /tmp/trace._core2_css.xt.gz
-rw-r--r-- 1 derick derick 3550 Sep 25 16:55 /tmp/trace._docs_.xt.gz
-rw-r--r-- 1 derick derick 2419 Sep 25 16:55 /tmp/trace._fonts_IBMPlexSans-RegularItalic-Latin1_woff2.xt.gz
-rw-r--r-- 1 derick derick 2474 Sep 25 16:55 /tmp/trace._images_logos_11com7_svg.xt.gz
-rw-r--r-- 1 derick derick 2507 Sep 25 16:55 /tmp/trace._images_logos_io_svg.xt.gz
-rw-r--r-- 1 derick derick 2530 Sep 25 16:55 /tmp/trace._images_logos_private-packagist_svg.xt.gz
-rw-r--r-- 1 derick derick 2455 Sep 25 16:55 /tmp/trace._images_logos_typo3_svg.xt.gz
-rw-r--r-- 1 derick derick 2523 Sep 25 16:55 /tmp/trace._images_logos_xdebug-cloud_svg.xt.gz
-rw-r--r-- 1 derick derick 6165 Sep 25 16:55 /tmp/trace._.xt.gz
</pre><p>Because we go through our PHP router process, there are also files for images and fonts.</p><p>The important ones are:</p><pre>-rw-r--r-- 1 derick derick 3550 Sep 25 16:55 /tmp/trace._docs_.xt.gz
-rw-r--r-- 1 derick derick 6165 Sep 25 16:55 /tmp/trace._.xt.gz
</pre><p>The contents of these files look like:</p><pre>{main};require_once;require_once 3046
{main};require_once;ComposerAutoloaderInit7d176ec022516f68e20dcb88554529a8::getLoader;require 7043
{main};require_once;ComposerAutoloaderInit7d176ec022516f68e20dcb88554529a8::getLoader;spl_autoload_register 9408
{main};require_once;ComposerAutoloaderInit7d176ec022516f68e20dcb88554529a8::getLoader;ComposerAutoloaderInit7d176ec022516f68e20dcb88554529a8::loadClassLoader;require 3176
{main};require_once;ComposerAutoloaderInit7d176ec022516f68e20dcb88554529a8::getLoader;ComposerAutoloaderInit7d176ec022516f68e20dcb88554529a8::loadClassLoader 41368
{main};require_once;ComposerAutoloaderInit7d176ec022516f68e20dcb88554529a8::getLoader;dirname 6061
…
</pre><p>In order to create a flame graph, we need to pass this through a Perl script. You can find this script by cloning the flamegraph GIT repository at <a href="https://github.com/brendangregg/FlameGraph">https://github.com/brendangregg/FlameGraph</a></p><p>Xdebug automatically compresses trace files, which means we need to use <code>zcat</code> as the <code>flamegraph.pl</code> script tool does not understand that. The output needs to be redirected to a file. On one line, we enter:</p><pre>zcat /tmp/trace._docs_.xt.gz
        | ~/dev/brendangreeg-FlameGraph/flamegraph.pl
        &gt; /tmp/flame-docs.svg
</pre><p>You can now open this SVG file you can then open in a browser.</p><p>The stack shows how deep the code goes, and interestingly, for most of it, you'll see that a lot of time is taken up by Composer, as well as requiring other files.</p><p>You can dive in by clicking on specific bits. For example, I'll click on my template default controller:</p><p>You can reset the zoom in the top left.</p><p>Xdebug's website is not very complex, and for your own code expect to see a lot more complicated flamegraph.</p><p>Once you're done, please don't forget to turn off the tracer, as it will fill up your hard drive.</p><p>This new flamegraph trace format is new in Xdebug 3.3, out soon.</p>]]></description>
      <link>https://derickrethans.nl/flamboyant-flamegraphs.html</link>
      <guid>https://derickrethans.nl/flamboyant-flamegraphs.html</guid>
      <pubDate>Tue, 07 Nov 2023 16:00:00 +0100</pubDate>
    </item>
    <item>
      <title><![CDATA[PHP 8.3.0 RC 5 available for testing - PHP: Hypertext Preprocessor]]></title>
      <description><![CDATA[<div id="intro" class="clearfix container hero"><img class="hero-logo" src="https://www.php.net/images/logos/php-logo-white.svg" alt="php" width="240" height="120" /><p class="hero-text">A <strong>popular general-purpose scripting language</strong> that is especially suited to web development.<br />Fast, flexible and pragmatic, PHP powers everything from your blog to the most popular websites in the world.</p><p><a href="https://www.php.net/releases/8.2/index.php" class="hero-btn hero-btn-primary">What's new in 8.2</a> <a href="https://www.php.net/downloads.php" class="hero-btn hero-btn-secondary">Download</a></p><ul class="hero-versions"><li class="hero-version"><a class="hero-version-link" href="https://www.php.net/downloads.php#v8.2.11">8.2.11</a> · <a class="notes" href="https://www.php.net/ChangeLog-8.php#8.2.11">Changelog</a> · <a class="notes" href="https://www.php.net/migration82">Upgrading</a></li>
<li class="hero-version"><a class="hero-version-link" href="https://www.php.net/downloads.php#v8.1.24">8.1.24</a> · <a class="notes" href="https://www.php.net/ChangeLog-8.php#8.1.24">Changelog</a> · <a class="notes" href="https://www.php.net/migration81">Upgrading</a></li>
<li class="hero-version"><a class="hero-version-link" href="https://www.php.net/downloads.php#v8.0.30">8.0.30</a> · <a class="notes" href="https://www.php.net/ChangeLog-8.php#8.0.30">Changelog</a> · <a class="notes" href="https://www.php.net/migration80">Upgrading</a></li>
</ul></div><div id="layout" class="clearfix"><section id="layout-content"><div class="home-content"><article class="newsentry"><header class="title"><time datetime="2023-10-26T15:00:24+00:00">26 Oct 2023</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the release of PHP 8.3.0, RC 5. This is the fifth release candidate, continuing the PHP 8.3 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php83">PHP Wiki</a>.</p><p>For source downloads of PHP 8.3.0, RC 5 please visit the <a href="https://downloads.php.net/~jakub/">download page</a>.</p><p>Please carefully test this version and report any issues found in the <a href="https://github.com/php/php-src/issues">bug reporting system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.3.0RC5/NEWS">NEWS</a> file or the <a href="https://github.com/php/php-src/blob/php-8.3.0RC5/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be the fourth release candidate (RC 5), planned for 26 October 2023.</p><p>The signatures for the release can be found in <a href="https://gist.github.com/bukka/c11ab353c69443c482219515838ed15a">the manifest</a> or on <a href="https://qa.php.net/">the QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-10-12T07:45:43-07:00">12 Oct 2023</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the release of PHP 8.3.0, RC 4. This is the fourth release candidate, continuing the PHP 8.3 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php83">PHP Wiki</a>.</p><p>For source downloads of PHP 8.3.0, RC 4 please visit the <a href="https://downloads.php.net/~eric/">download page</a>.</p><p>Please carefully test this version and report any issues found in the <a href="https://github.com/php/php-src/issues">bug reporting system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.3.0RC4/NEWS">NEWS</a> file or the <a href="https://github.com/php/php-src/blob/php-8.3.0RC4/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be the fifth release candidate (RC 5), planned for 26 October 2023.</p><p>The signatures for the release can be found in <a href="https://gist.github.com/ericmann/5531915317a5186bb4359bdd6c10e299">the manifest</a> or on <a href="https://qa.php.net/">the QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-09-28T18:04:30+00:00">28 Sep 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.1.24. This is a bug fix release.</p><p>All PHP 8.1 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.1.24 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.1.24">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-09-28T15:52:06+00:00">28 Sep 2023</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the release of PHP 8.3.0, RC 3. This is the third release candidate, continuing the PHP 8.3 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php83">PHP Wiki</a>.</p><p>For source downloads of PHP 8.3.0, RC 3 please visit the <a href="https://downloads.php.net/~jakub/">download page</a>.</p><p>Please carefully test this version and report any issues found in the <a href="https://github.com/php/php-src/issues">bug reporting system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.3.0RC3/NEWS">NEWS</a> file or the <a href="https://github.com/php/php-src/blob/php-8.3.0RC3/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be the fourth release candidate (RC 4), planned for 12 October 2023.</p><p>The signatures for the release can be found in <a href="https://gist.github.com/bukka/20e2e90e1ef16eb24c333f375203292e">the manifest</a> or on <a href="https://qa.php.net/">the QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-09-28T14:31:39+00:00">28 Sep 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.11. This is a bug fix release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.11 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.11">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-09-14T03:51:40-07:00">14 Sep 2023</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the release of PHP 8.3.0, RC 2. This is the second release candidate, continuing the PHP 8.3 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php83">PHP Wiki</a>.</p><p>For source downloads of PHP 8.3.0, RC 2 please visit the <a href="https://downloads.php.net/~eric/">download page</a>.</p><p>Please carefully test this version and report any issues found in the <a href="http://bugs.php.net">bug reporting system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.3.0RC2/NEWS">NEWS</a> file or the <a href="https://github.com/php/php-src/blob/php-8.3.0RC2/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be the third release candidate (RC 3), planned for 28 September 2023.</p><p>The signatures for the release can be found in <a href="https://gist.github.com/ericmann/d8c56e1244679ab41672dcfdbea2b0a6">the manifest</a> or on <a href="https://qa.php.net/">the QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-08-31T16:37:56+00:00">31 Aug 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.1.23. This is a bug fix release.</p><p>All PHP 8.1 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.1.23 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.1.23">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-08-31T16:15:39+00:00">31 Aug 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.10. This is a bug fix release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.10 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.10">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-08-31T11:23:53+00:00">31 Aug 2023</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the release of PHP 8.3.0, RC 1. This is the first release candidate, continuing the PHP 8.3 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php83">PHP Wiki</a>.</p><p>For source downloads of PHP 8.3.0, RC 1 please visit the <a href="https://downloads.php.net/~jakub/">download page</a>.</p><p>Please carefully test this version and report any issues found in the <a href="http://bugs.php.net">bug reporting system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.3.0RC1/NEWS">NEWS</a> file or the <a href="https://github.com/php/php-src/blob/php-8.3.0RC1/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be the second release candidate (RC 2), planned for 14 September 2023.</p><p>The signatures for the release can be found in <a href="https://gist.github.com/bukka/b5d4f8f27d1f013837e1f596d90ea1fc">the manifest</a> or on <a href="https://qa.php.net/">the QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-08-17T07:26:35-07:00">17 Aug 2023</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the third beta release of PHP 8.3.0, Beta 3. This continues the PHP 8.3 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php83">PHP Wiki</a>.</p><p>For source downloads of PHP 8.3.0 Beta 3 please visit the <a href="https://downloads.php.net/~eric">download page</a>.</p><p>Please carefully test this version and report any issues found in the <a href="https://github.com/php/php-src/issues">bug reporting system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.3.0beta3/NEWS">NEWS</a> file, or the <a href="https://github.com/php/php-src/blob/php-8.3.0beta3/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be RC 1, planned for Aug 31 2023.</p><p>The signatures for the release can be found in <a href="https://gist.github.com/ericmann/8ea0c14efef9b0e0a7e4222e06ed5097">the manifest</a> or on <a href="https://qa.php.net/">the QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-08-16T18:06:57+00:00">16 Aug 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.9. This is a security release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p><strong>Windows source and binaries are not synchronized and do not contain a fix for GH-11854.</strong></p><p>For source downloads of PHP 8.2.9 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.9">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-08-04T18:29:29+00:00">04 Aug 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.0.30. This is a security release.</p><p>All PHP 8.0 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.0.30 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.0.30">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-08-03T11:50:26-07:00">03 Aug 2023</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the second beta release of PHP 8.3.0, Beta 2. This continues the PHP 8.3 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php83">PHP Wiki</a>.</p><p>For source downloads of PHP 8.3.0 Beta 2 please visit the <a href="https://downloads.php.net/~jakub">download page</a>.</p><p>Please carefully test this version and report any issues found in the <a href="https://github.com/php/php-src/issues">bug reporting system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.3.0beta2/NEWS">NEWS</a> file, or the <a href="https://github.com/php/php-src/blob/php-8.3.0beta2/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be Beta 3, planned for Aug 17 2023.</p><p>The signatures for the release can be found in <a href="https://gist.github.com/bukka/31646ada5b94b4d2b78e0551905f5745">the manifest</a> or on <a href="https://qa.php.net/">the QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-08-03T15:07:49+00:00">03 Aug 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.1.22. This is a security release.</p><p>All PHP 8.1 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.1.22 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.1.22">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-07-20T08:11:32-07:00">20 Jul 2023</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the first beta release of PHP 8.3.0, Beta 1. This continues the PHP 8.3 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php83">PHP Wiki</a>.</p><p>For source downloads of PHP 8.3.0 Beta 1 please visit the <a href="https://downloads.php.net/~eric">download page</a>.</p><p>Please carefully test this version and report any issues found in the <a href="https://github.com/php/php-src/issues">bug reporting system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.3.0beta1/NEWS">NEWS</a> file, or the <a href="https://github.com/php/php-src/blob/php-8.3.0beta1/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be Beta 2, planned for Aug 3 2023.</p><p>The signatures for the release can be found in <a href="https://gist.github.com/ericmann/5d3b2ddc1c8696510614d81690d4b347">the manifest</a> or on <a href="https://qa.php.net/">the QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-07-06T14:45:21+00:00">06 Jul 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.1.21. This is a bug fix release.</p><p>All PHP 8.1 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.1.21 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.1.21">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-07-06T09:47:01+00:00">06 Jul 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.8. This is a bug fix release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.8 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.8">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-07-06T09:43:06+00:00">06 Jul 2023</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the third testing release of PHP 8.3.0, Alpha 3. This continues the PHP 8.3 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php83">PHP Wiki</a>.</p><p>For source downloads of PHP 8.3.0 Alpha 3 please visit the <a href="https://downloads.php.net/~jakub/">download page</a>.</p><p>Please carefully test this version and report any issues found in the <a href="https://github.com/php/php-src/issues">bug reporting system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.3.0alpha3/NEWS">NEWS</a> file, or the <a href="https://github.com/php/php-src/blob/php-8.3.0alpha3/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be Beta 1, planned for 20 Jul 2023.</p><p>The signatures for the release can be found in the <a href="https://gist.github.com/bukka/9324ba069ce9588c5000a60fbb8cccbb">manifest</a> or on the <a href="https://qa.php.net/">QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-06-22T11:15:33-07:00">22 Jun 2023</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the second testing release of PHP 8.3.0, Alpha 2. This continues the PHP 8.3 release cycle, the rouch outline of which is specified in the <a href="https://wiki.php.net/todo/php83">PHP Wiki</a>.</p><p>For source downloads of PHP 8.3.0 Alpha 2 please visit <a href="https://downloads.php.net/~eric/">download page</a>.</p><p>Please carefully test this version and report any issues found in the <a href="https://github.com/php/php-src/issues">bug reporting system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.3.0alpha2/NEWS">NEWS</a> file, or the <a href="https://github.com/php/php-src/blob/php-8.3.0alpha2/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be Alpha 3, planned for 6 July 2023.</p><p>The signatures for this release can be found in <a href="https://gist.github.com/ericmann/7355303dbb2d350522b155349c61fc7c">the manifest</a> or on <a href="https://qa.php.net/">the QA site</a>.</p><p>Thank you for helping us make PHP better!</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-06-08T18:24:16+00:00">08 Jun 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.1.20. This is a security release.</p><p>All PHP 8.1 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.1.20 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.1.20">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-06-08T18:14:14+00:00">08 Jun 2023</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the first testing release of PHP 8.3.0, Alpha 1. This starts the PHP 8.3 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php83">PHP Wiki</a>.</p><p>For source downloads of PHP 8.3.0 Alpha 1 please visit the <a href="https://downloads.php.net/~jakub/">download page</a>.</p><p>Please carefully test this version and report any issues found using <a href="https://github.com/php/php-src/issues">the bug tracking system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.3.0alpha1/NEWS">NEWS</a> file, or the <a href="https://github.com/php/php-src/blob/php-8.3.0alpha1/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be Alpha 2, planned for 22 Jun 2023.</p><p>The signatures for the release can be found in the <a href="https://gist.github.com/bukka/66530718f180092527a741d023492b23">manifest</a> or on the <a href="https://qa.php.net/">QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-06-08T16:50:22+00:00">08 Jun 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.7. This is a security release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.7 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.7">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-06-08T09:03:22+00:00">08 Jun 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.0.29. This is a security release.</p><p>All PHP 8.0 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.0.29 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/#php-8.0">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.0.29">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-05-11T23:40:59+00:00">11 May 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.1.19. This is a bug fix release.</p><p>All PHP 8.1 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.1.19 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.1.19">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-05-11T10:08:59+00:00">11 May 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.6. This is a bug fix release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.6 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.6">ChangeLog</a>.</p></div></article></div></section><aside class="tips"><div class="inner"><p class="panel"><a href="https://www.php.net/cal.php">User Group Events</a></p><p class="panel"><a href="https://www.php.net/thanks.php">Special Thanks</a></p></div>
</aside></div>]]></description>
      <link>https://www.php.net/index.php#2023-10-26-1</link>
      <guid>https://www.php.net/index.php#2023-10-26-1</guid>
      <pubDate>Thu, 26 Oct 2023 02:00:00 +0200</pubDate>
    </item>
    <item>
      <title><![CDATA[Why aren't there more 80% jobs? - Evert Pot]]></title>
      <description><![CDATA[<p>There’s been a bit of a trend recently for some companies to move to 4-day workweeks. This is making a decent amount of noise, but the actual number of companies offering this still seems pretty few and far between. It’s not hard to imagine why CEOs might feel this is risky, considering that many don’t even trust people to work from home.</p><p>What I don’t see much are 80% jobs, which are 32 hour jobs, at 80% salary. This should be a low-risk proposition that I think a lot of people in the tech industry would take, if it were an option.</p><h2 id="my-background">My background</h2><p>I grew up in the Netherlands, but I moved to Canada for my first programmer job at age 20. I stayed for a few years, moved back and started a job there, and eventually moved <em>back</em> to Canada again and pretty much settled here.</p><p>I got strong roots and professional experience in both places, but there was one thing that surprised me most in the Netherlands that I haven’t really seen in North America.</p><p>Apparently Netherlands has a very high rate of part-time careers. Statstics suggest that they are the highest in the world by a large margin. My personal experience matches this too. I know a number of people in the Netherlands that don’t work full-time, and I think there are more opportunities for part-time career jobs. I don’t see them much in North America.</p><p>My first-hand experience is when I was interviewing a few years into my career at a company named Ibuildings in Utrecht, Netherlands. After the interview I was told I pretty much had the job, and then the interviewer asked me if I wanted to work 4 or 5 days per week.</p><p>I only had Canadian work experience, so I was pretty shocked being asked this. Picking 4 days seemed like a no-brainer to me. I would get paid for 32 hours per week, instead of 40 and got to pick a day of the week I wanted off (I picked Friday). At this company I believe most people took the 4-day option. So yes, I got paid 20% less, but with the tax bracket I was in this was closer to 10%.</p><p>For me it was great. 5 days actually feels like a lot, and 2 days in a weekend never feels quite enough. A sentiment so common it’s boring talk about it. I used the extra time to work on open source, errands, and picked a few small freelance gigs here and there.</p><p>I’m leaning pretty socialist, but even with a capitalist hat on, I’m surprised this doesn’t happen more. Why not give employees the option to do this? Not everyone will take the option, but for those that do here’s some advantages:</p><h2 id="advantages-of-offering-80-jobs">Advantages of offering 80% jobs</h2><ul><li>For the salary cost of 4 employees at 40 hours, you get 5 employees at 32 hours.</li>
<li>Those 5 employees are more rested, and may be generally happier.</li>
<li>There’s a lower risk of burn-out and attrition.</li>
<li>You get the combined experience of 5 people instead of 4.</li>
<li>Also I don’t believe for the 80% workers, you only get 80% output. Most people just aren’t productive all the time.</li>
<li>Advertising this as a benefit in your company may also be attractive to candidates for hiring.</li>
</ul><p>There are also some drawbacks. Every employee will have some overhead such as a laptop, benefits and general admin. Probably a larger expense is the cost to recruit, although in the long run a lower attrition rate might make up for that a bit.</p><p>But my intuition tells me that this overhead is probably well worth the benefit of a smarter, larger, happier workforce.</p><p>Some notes:</p><ul><li>I want to stress that working 4 days should be presented as a <em>choice</em>. Some people prefer to work more for more money, and you don’t want to scare them.</li>
<li>Another, even more lightweight option for irriationally risk-averse traditionalists is to offer 90% jobs, resulting in an extra day every 2 weeks.</li>
</ul>]]></description>
      <link>https://evertpot.com/on-80-percent-jobs/</link>
      <guid>https://evertpot.com/on-80-percent-jobs/</guid>
      <pubDate>Thu, 12 Oct 2023 22:29:00 +0200</pubDate>
    </item>
    <item>
      <title><![CDATA[PHP 8.3.0 RC 4 available for testing - PHP: Hypertext Preprocessor]]></title>
      <description><![CDATA[<div id="intro" class="clearfix container hero"><img class="hero-logo" src="https://www.php.net/images/logos/php-logo-white.svg" alt="php" width="240" height="120" /><p class="hero-text">A <strong>popular general-purpose scripting language</strong> that is especially suited to web development.Fast, flexible and pragmatic, PHP powers everything from your blog to the most popular websites in the world.</p><p><a href="https://www.php.net/releases/8.2/index.php" class="hero-btn hero-btn-primary">What's new in 8.2</a> <a href="https://www.php.net/downloads.php" class="hero-btn hero-btn-secondary">Download</a></p><ul class="hero-versions"><li class="hero-version"><a class="hero-version-link" href="https://www.php.net/downloads.php#v8.2.11">8.2.11</a> · <a class="notes" href="https://www.php.net/ChangeLog-8.php#8.2.11">Changelog</a> · <a class="notes" href="https://www.php.net/migration82">Upgrading</a></li>
<li class="hero-version"><a class="hero-version-link" href="https://www.php.net/downloads.php#v8.1.24">8.1.24</a> · <a class="notes" href="https://www.php.net/ChangeLog-8.php#8.1.24">Changelog</a> · <a class="notes" href="https://www.php.net/migration81">Upgrading</a></li>
<li class="hero-version"><a class="hero-version-link" href="https://www.php.net/downloads.php#v8.0.30">8.0.30</a> · <a class="notes" href="https://www.php.net/ChangeLog-8.php#8.0.30">Changelog</a> · <a class="notes" href="https://www.php.net/migration80">Upgrading</a></li>
</ul></div><div id="layout" class="clearfix"><section id="layout-content"><div class="home-content"><article class="newsentry"><header class="title"><time datetime="2023-10-12T07:45:43-07:00">12 Oct 2023</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the release of PHP 8.3.0, RC 4. This is the fourth release candidate, continuing the PHP 8.3 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php83">PHP Wiki</a>.</p><p>For source downloads of PHP 8.3.0, RC 4 please visit the <a href="https://downloads.php.net/~eric/">download page</a>.</p><p>Please carefully test this version and report any issues found in the <a href="https://github.com/php/php-src/issues">bug reporting system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.3.0RC4/NEWS">NEWS</a> file or the <a href="https://github.com/php/php-src/blob/php-8.3.0RC4/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be the fifth release candidate (RC 5), planned for 26 October 2023.</p><p>The signatures for the release can be found in <a href="https://gist.github.com/ericmann/5531915317a5186bb4359bdd6c10e299">the manifest</a> or on <a href="https://qa.php.net/">the QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-09-28T18:04:30+00:00">28 Sep 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.1.24. This is a bug fix release.</p><p>All PHP 8.1 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.1.24 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.1.24">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-09-28T15:52:06+00:00">28 Sep 2023</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the release of PHP 8.3.0, RC 3. This is the third release candidate, continuing the PHP 8.3 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php83">PHP Wiki</a>.</p><p>For source downloads of PHP 8.3.0, RC 3 please visit the <a href="https://downloads.php.net/~jakub/">download page</a>.</p><p>Please carefully test this version and report any issues found in the <a href="https://github.com/php/php-src/issues">bug reporting system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.3.0RC3/NEWS">NEWS</a> file or the <a href="https://github.com/php/php-src/blob/php-8.3.0RC3/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be the fourth release candidate (RC 4), planned for 12 October 2023.</p><p>The signatures for the release can be found in <a href="https://gist.github.com/bukka/20e2e90e1ef16eb24c333f375203292e">the manifest</a> or on <a href="https://qa.php.net/">the QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-09-28T14:31:39+00:00">28 Sep 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.11. This is a bug fix release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.11 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.11">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-09-14T03:51:40-07:00">14 Sep 2023</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the release of PHP 8.3.0, RC 2. This is the second release candidate, continuing the PHP 8.3 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php83">PHP Wiki</a>.</p><p>For source downloads of PHP 8.3.0, RC 2 please visit the <a href="https://downloads.php.net/~eric/">download page</a>.</p><p>Please carefully test this version and report any issues found in the <a href="http://bugs.php.net">bug reporting system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.3.0RC2/NEWS">NEWS</a> file or the <a href="https://github.com/php/php-src/blob/php-8.3.0RC2/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be the third release candidate (RC 3), planned for 28 September 2023.</p><p>The signatures for the release can be found in <a href="https://gist.github.com/ericmann/d8c56e1244679ab41672dcfdbea2b0a6">the manifest</a> or on <a href="https://qa.php.net/">the QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-08-31T16:37:56+00:00">31 Aug 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.1.23. This is a bug fix release.</p><p>All PHP 8.1 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.1.23 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.1.23">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-08-31T16:15:39+00:00">31 Aug 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.10. This is a bug fix release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.10 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.10">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-08-31T11:23:53+00:00">31 Aug 2023</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the release of PHP 8.3.0, RC 1. This is the first release candidate, continuing the PHP 8.3 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php83">PHP Wiki</a>.</p><p>For source downloads of PHP 8.3.0, RC 1 please visit the <a href="https://downloads.php.net/~jakub/">download page</a>.</p><p>Please carefully test this version and report any issues found in the <a href="http://bugs.php.net">bug reporting system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.3.0RC1/NEWS">NEWS</a> file or the <a href="https://github.com/php/php-src/blob/php-8.3.0RC1/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be the second release candidate (RC 2), planned for 14 September 2023.</p><p>The signatures for the release can be found in <a href="https://gist.github.com/bukka/b5d4f8f27d1f013837e1f596d90ea1fc">the manifest</a> or on <a href="https://qa.php.net/">the QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-08-17T07:26:35-07:00">17 Aug 2023</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the third beta release of PHP 8.3.0, Beta 3. This continues the PHP 8.3 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php83">PHP Wiki</a>.</p><p>For source downloads of PHP 8.3.0 Beta 3 please visit the <a href="https://downloads.php.net/~eric">download page</a>.</p><p>Please carefully test this version and report any issues found in the <a href="https://github.com/php/php-src/issues">bug reporting system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.3.0beta3/NEWS">NEWS</a> file, or the <a href="https://github.com/php/php-src/blob/php-8.3.0beta3/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be RC 1, planned for Aug 31 2023.</p><p>The signatures for the release can be found in <a href="https://gist.github.com/ericmann/8ea0c14efef9b0e0a7e4222e06ed5097">the manifest</a> or on <a href="https://qa.php.net/">the QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-08-16T18:06:57+00:00">16 Aug 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.9. This is a security release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p><strong>Windows source and binaries are not synchronized and do not contain a fix for GH-11854.</strong></p><p>For source downloads of PHP 8.2.9 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.9">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-08-04T18:29:29+00:00">04 Aug 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.0.30. This is a security release.</p><p>All PHP 8.0 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.0.30 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.0.30">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-08-03T11:50:26-07:00">03 Aug 2023</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the second beta release of PHP 8.3.0, Beta 2. This continues the PHP 8.3 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php83">PHP Wiki</a>.</p><p>For source downloads of PHP 8.3.0 Beta 2 please visit the <a href="https://downloads.php.net/~jakub">download page</a>.</p><p>Please carefully test this version and report any issues found in the <a href="https://github.com/php/php-src/issues">bug reporting system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.3.0beta2/NEWS">NEWS</a> file, or the <a href="https://github.com/php/php-src/blob/php-8.3.0beta2/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be Beta 3, planned for Aug 17 2023.</p><p>The signatures for the release can be found in <a href="https://gist.github.com/bukka/31646ada5b94b4d2b78e0551905f5745">the manifest</a> or on <a href="https://qa.php.net/">the QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-08-03T15:07:49+00:00">03 Aug 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.1.22. This is a security release.</p><p>All PHP 8.1 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.1.22 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.1.22">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-07-20T08:11:32-07:00">20 Jul 2023</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the first beta release of PHP 8.3.0, Beta 1. This continues the PHP 8.3 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php83">PHP Wiki</a>.</p><p>For source downloads of PHP 8.3.0 Beta 1 please visit the <a href="https://downloads.php.net/~eric">download page</a>.</p><p>Please carefully test this version and report any issues found in the <a href="https://github.com/php/php-src/issues">bug reporting system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.3.0beta1/NEWS">NEWS</a> file, or the <a href="https://github.com/php/php-src/blob/php-8.3.0beta1/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be Beta 2, planned for Aug 3 2023.</p><p>The signatures for the release can be found in <a href="https://gist.github.com/ericmann/5d3b2ddc1c8696510614d81690d4b347">the manifest</a> or on <a href="https://qa.php.net/">the QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-07-06T14:45:21+00:00">06 Jul 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.1.21. This is a bug fix release.</p><p>All PHP 8.1 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.1.21 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.1.21">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-07-06T09:47:01+00:00">06 Jul 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.8. This is a bug fix release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.8 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.8">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-07-06T09:43:06+00:00">06 Jul 2023</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the third testing release of PHP 8.3.0, Alpha 3. This continues the PHP 8.3 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php83">PHP Wiki</a>.</p><p>For source downloads of PHP 8.3.0 Alpha 3 please visit the <a href="https://downloads.php.net/~jakub/">download page</a>.</p><p>Please carefully test this version and report any issues found in the <a href="https://github.com/php/php-src/issues">bug reporting system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.3.0alpha3/NEWS">NEWS</a> file, or the <a href="https://github.com/php/php-src/blob/php-8.3.0alpha3/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be Beta 1, planned for 20 Jul 2023.</p><p>The signatures for the release can be found in the <a href="https://gist.github.com/bukka/9324ba069ce9588c5000a60fbb8cccbb">manifest</a> or on the <a href="https://qa.php.net/">QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-06-22T11:15:33-07:00">22 Jun 2023</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the second testing release of PHP 8.3.0, Alpha 2. This continues the PHP 8.3 release cycle, the rouch outline of which is specified in the <a href="https://wiki.php.net/todo/php83">PHP Wiki</a>.</p><p>For source downloads of PHP 8.3.0 Alpha 2 please visit <a href="https://downloads.php.net/~eric/">download page</a>.</p><p>Please carefully test this version and report any issues found in the <a href="https://github.com/php/php-src/issues">bug reporting system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.3.0alpha2/NEWS">NEWS</a> file, or the <a href="https://github.com/php/php-src/blob/php-8.3.0alpha2/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be Alpha 3, planned for 6 July 2023.</p><p>The signatures for this release can be found in <a href="https://gist.github.com/ericmann/7355303dbb2d350522b155349c61fc7c">the manifest</a> or on <a href="https://qa.php.net/">the QA site</a>.</p><p>Thank you for helping us make PHP better!</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-06-08T18:24:16+00:00">08 Jun 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.1.20. This is a security release.</p><p>All PHP 8.1 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.1.20 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.1.20">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-06-08T18:14:14+00:00">08 Jun 2023</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the first testing release of PHP 8.3.0, Alpha 1. This starts the PHP 8.3 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php83">PHP Wiki</a>.</p><p>For source downloads of PHP 8.3.0 Alpha 1 please visit the <a href="https://downloads.php.net/~jakub/">download page</a>.</p><p>Please carefully test this version and report any issues found using <a href="https://github.com/php/php-src/issues">the bug tracking system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.3.0alpha1/NEWS">NEWS</a> file, or the <a href="https://github.com/php/php-src/blob/php-8.3.0alpha1/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be Alpha 2, planned for 22 Jun 2023.</p><p>The signatures for the release can be found in the <a href="https://gist.github.com/bukka/66530718f180092527a741d023492b23">manifest</a> or on the <a href="https://qa.php.net/">QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-06-08T16:50:22+00:00">08 Jun 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.7. This is a security release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.7 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.7">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-06-08T09:03:22+00:00">08 Jun 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.0.29. This is a security release.</p><p>All PHP 8.0 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.0.29 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/#php-8.0">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.0.29">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-05-11T23:40:59+00:00">11 May 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.1.19. This is a bug fix release.</p><p>All PHP 8.1 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.1.19 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.1.19">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-05-11T10:08:59+00:00">11 May 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.6. This is a bug fix release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.6 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.6">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-04-13T23:59:59+00:00">13 Apr 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.1.18. This is a bug fix release.</p><p>All PHP 8.1 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.1.18 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.1.18">ChangeLog</a>.</p></div></article></div></section><aside class="tips"><div class="inner"><p class="panel"><a href="https://www.php.net/cal.php">User Group Events</a></p><p class="panel"><a href="https://www.php.net/thanks.php">Special Thanks</a></p></div>
</aside></div>]]></description>
      <link>https://www.php.net/index.php#2023-10-12-1</link>
      <guid>https://www.php.net/index.php#2023-10-12-1</guid>
      <pubDate>Thu, 12 Oct 2023 02:00:00 +0200</pubDate>
    </item>
    <item>
      <title><![CDATA[Xdebug Update: September 2023 - Derick Rethans]]></title>
      <description><![CDATA[<p>In this monthly update I explain what happened with Xdebug development in the past month. These are normally published on the first Tuesday on or after the 5th of each month.</p><p><a href="https://www.patreon.com/derickr">Patreon</a> and <a href="https://github.com/sponsors/derickr/">GitHub</a> supporters will get it earlier, around the first of each month.</p><p>You can <a href="https://www.patreon.com/bePatron?u=7864328">become a patron</a> or support me through <a href="https://github.com/sponsors/derickr">GitHub Sponsors</a>. I am currently 37% towards my $2,500 per month goal, which is set to allow continued maintenance of Xdebug.</p><p>If you are leading a team or company, then it is also possible to support Xdebug through <a href="https://xdebug.org/support">a subscription</a>.</p><p>In the last month, I spend around 28 hours on Xdebug, with 25 hours funded.</p><div class="articleSubSection"><h2>Towards Xdebug 3.3</h2><p>In September I released a first alpha release of Xdebug 3.3 so that people trying out PHP 8.3 Release Candidates have a compatible Xdebug to test with.</p><p>This quickly followed by a second alpha version due to issues with the PECL website. Instead of mangling UTF-8 characters, it stopped accepting them altogether.</p><p>I have reintroduced the <code>xdebug.collect_params</code> setting, which I had removed in Xdebug 3.0. Instead of the setting, Xdebug would just always collect functions' and methods' arguments while tracing. However, some users were suggesting that this created too much information which was not always needed. With the setting restored, you can now again hide these function arguments from trace files.</p><p>As frameworks are getting more complicated, they are more likely to hit Xdebug's default <code>xdebug.max_nesting_level</code> limit of <code>256</code>. In Xdebug 3.3, this will now be <code>512</code>.</p><p>The maximum nesting level setting is now less important that it was all these years ago. The PHP engine now uses stack in a more economic way. This feature unfortunately is negated when extensions override PHP's internal execution method, which is what Xdebug has to do to capture function calls for tracing, profiling, and certain breakpoints.</p><p>In PHP 8.1 a new Observer API was added, which would allow extensions to observe user-land function calls without having to override the internal execution method. This means that the stack is used more sparingly again. It also would allow for these extensions to work better with opcache enabled.</p><p>I am currently in the process of investigating whether Xdebug can make use of this Observer API as well, while maintaining all its functionality and without BC breaks. I will keep you updated in the next monthly update.</p><p>Beyond this, I will continue to work on the features and issues on the <a href="https://bugs.xdebug.org/roadmap_page.php?version_id=101">3.3 roadmap</a>, without any guarantees these tickets will be implemented.</p></div><div class="articleSubSection"><h2>Xdebug Videos</h2><p>I have published one new videos in the last month:</p><ul><li>
<p><a href="https://www.youtube.com/watch?v=_3RkGZK-UC8">Xdebug 3: Using the DBGp Proxy</a></p>
</li>
</ul><p>Let me know what you'd like to see!</p><p>You can find all previous videos on my <a href="https://www.youtube.com/playlist?list=PLg9Kjjye-m1g_eXpdaifUqLqALLqZqKd4">YouTube channel</a>.</p></div><div class="articleSubSection"><h2>Business Supporter Scheme and Funding</h2><p>In the last month, no new business supporters signed up.</p><p>Besides business support, I also maintain a <a href="https://www.patreon.com/derickr">Patreon</a> page, a profile on <a href="https://github.com/sponsors/derickr">GitHub sponsors</a>, as well as an <a href="https://opencollective.com/xdebug">OpenCollective</a> organisation.</p></div><div class="articleSubSection"><h2>Xdebug Cloud</h2><p>Xdebug Cloud is the <em>Proxy As A Service</em> platform to allow for debugging in more scenarios, where it is hard, or impossible, to have Xdebug make a connection to the IDE. It is continuing to operate as Beta release.</p><p>Packages start at £49/month, and I have recently introduced a package for larger companies. This has a larger initial set of tokens, and discounted extra tokens.</p><p>If you want to be kept up to date with Xdebug Cloud, please sign up to the <a href="https://xdebug.cloud/newsletter">mailinglist</a>, which I will use to send out an update not more than once a month.</p></div>]]></description>
      <link>https://derickrethans.nl/xdebug-update-september-2023.html</link>
      <guid>https://derickrethans.nl/xdebug-update-september-2023.html</guid>
      <pubDate>Tue, 10 Oct 2023 16:00:00 +0200</pubDate>
    </item>
    <item>
      <title><![CDATA[PHP 8.3.0 RC 3 available for testing - PHP: Hypertext Preprocessor]]></title>
      <description><![CDATA[<div id="intro" class="clearfix container hero"><img class="hero-logo" src="https://www.php.net/images/logos/php-logo-white.svg" alt="php" width="240" height="120" /><p class="hero-text">A <strong>popular general-purpose scripting language</strong> that is especially suited to web development.Fast, flexible and pragmatic, PHP powers everything from your blog to the most popular websites in the world.</p><p><a href="https://www.php.net/releases/8.2/index.php" class="hero-btn hero-btn-primary">What's new in 8.2</a> <a href="https://www.php.net/downloads.php" class="hero-btn hero-btn-secondary">Download</a></p><ul class="hero-versions"><li class="hero-version"><a class="hero-version-link" href="https://www.php.net/downloads.php#v8.2.11">8.2.11</a> · <a class="notes" href="https://www.php.net/ChangeLog-8.php#8.2.11">Changelog</a> · <a class="notes" href="https://www.php.net/migration82">Upgrading</a></li>
<li class="hero-version"><a class="hero-version-link" href="https://www.php.net/downloads.php#v8.1.23">8.1.23</a> · <a class="notes" href="https://www.php.net/ChangeLog-8.php#8.1.23">Changelog</a> · <a class="notes" href="https://www.php.net/migration81">Upgrading</a></li>
<li class="hero-version"><a class="hero-version-link" href="https://www.php.net/downloads.php#v8.0.30">8.0.30</a> · <a class="notes" href="https://www.php.net/ChangeLog-8.php#8.0.30">Changelog</a> · <a class="notes" href="https://www.php.net/migration80">Upgrading</a></li>
</ul></div><div id="layout" class="clearfix"><section id="layout-content"><div class="home-content"><article class="newsentry"><header class="title"><time datetime="2023-09-28T15:52:06+00:00">28 Sep 2023</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the release of PHP 8.3.0, RC 3. This is the third release candidate, continuing the PHP 8.3 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php83">PHP Wiki</a>.</p><p>For source downloads of PHP 8.3.0, RC 3 please visit the <a href="https://downloads.php.net/~jakub/">download page</a>.</p><p>Please carefully test this version and report any issues found in the <a href="https://github.com/php/php-src/issues">bug reporting system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.3.0RC3/NEWS">NEWS</a> file or the <a href="https://github.com/php/php-src/blob/php-8.3.0RC3/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be the fourth release candidate (RC 4), planned for 12 October 2023.</p><p>The signatures for the release can be found in <a href="https://gist.github.com/bukka/20e2e90e1ef16eb24c333f375203292e">the manifest</a> or on <a href="https://qa.php.net/">the QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-09-28T14:31:39+00:00">28 Sep 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.11. This is a bug fix release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.11 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.11">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-09-14T03:51:40-07:00">14 Sep 2023</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the release of PHP 8.3.0, RC 2. This is the second release candidate, continuing the PHP 8.3 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php83">PHP Wiki</a>.</p><p>For source downloads of PHP 8.3.0, RC 2 please visit the <a href="https://downloads.php.net/~eric/">download page</a>.</p><p>Please carefully test this version and report any issues found in the <a href="http://bugs.php.net">bug reporting system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.3.0RC2/NEWS">NEWS</a> file or the <a href="https://github.com/php/php-src/blob/php-8.3.0RC2/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be the third release candidate (RC 3), planned for 28 September 2023.</p><p>The signatures for the release can be found in <a href="https://gist.github.com/ericmann/d8c56e1244679ab41672dcfdbea2b0a6">the manifest</a> or on <a href="https://qa.php.net/">the QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-08-31T16:37:56+00:00">31 Aug 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.1.23. This is a bug fix release.</p><p>All PHP 8.1 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.1.23 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.1.23">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-08-31T16:15:39+00:00">31 Aug 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.10. This is a bug fix release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.10 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.10">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-08-31T11:23:53+00:00">31 Aug 2023</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the release of PHP 8.3.0, RC 1. This is the first release candidate, continuing the PHP 8.3 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php83">PHP Wiki</a>.</p><p>For source downloads of PHP 8.3.0, RC 1 please visit the <a href="https://downloads.php.net/~jakub/">download page</a>.</p><p>Please carefully test this version and report any issues found in the <a href="http://bugs.php.net">bug reporting system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.3.0RC1/NEWS">NEWS</a> file or the <a href="https://github.com/php/php-src/blob/php-8.3.0RC1/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be the second release candidate (RC 2), planned for 14 September 2023.</p><p>The signatures for the release can be found in <a href="https://gist.github.com/bukka/b5d4f8f27d1f013837e1f596d90ea1fc">the manifest</a> or on <a href="https://qa.php.net/">the QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-08-17T07:26:35-07:00">17 Aug 2023</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the third beta release of PHP 8.3.0, Beta 3. This continues the PHP 8.3 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php83">PHP Wiki</a>.</p><p>For source downloads of PHP 8.3.0 Beta 3 please visit the <a href="https://downloads.php.net/~eric">download page</a>.</p><p>Please carefully test this version and report any issues found in the <a href="https://github.com/php/php-src/issues">bug reporting system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.3.0beta3/NEWS">NEWS</a> file, or the <a href="https://github.com/php/php-src/blob/php-8.3.0beta3/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be RC 1, planned for Aug 31 2023.</p><p>The signatures for the release can be found in <a href="https://gist.github.com/ericmann/8ea0c14efef9b0e0a7e4222e06ed5097">the manifest</a> or on <a href="https://qa.php.net/">the QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-08-16T18:06:57+00:00">16 Aug 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.9. This is a security release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p><strong>Windows source and binaries are not synchronized and do not contain a fix for GH-11854.</strong></p><p>For source downloads of PHP 8.2.9 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.9">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-08-04T18:29:29+00:00">04 Aug 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.0.30. This is a security release.</p><p>All PHP 8.0 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.0.30 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.0.30">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-08-03T11:50:26-07:00">03 Aug 2023</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the second beta release of PHP 8.3.0, Beta 2. This continues the PHP 8.3 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php83">PHP Wiki</a>.</p><p>For source downloads of PHP 8.3.0 Beta 2 please visit the <a href="https://downloads.php.net/~jakub">download page</a>.</p><p>Please carefully test this version and report any issues found in the <a href="https://github.com/php/php-src/issues">bug reporting system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.3.0beta2/NEWS">NEWS</a> file, or the <a href="https://github.com/php/php-src/blob/php-8.3.0beta2/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be Beta 3, planned for Aug 17 2023.</p><p>The signatures for the release can be found in <a href="https://gist.github.com/bukka/31646ada5b94b4d2b78e0551905f5745">the manifest</a> or on <a href="https://qa.php.net/">the QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-08-03T15:07:49+00:00">03 Aug 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.1.22. This is a security release.</p><p>All PHP 8.1 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.1.22 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.1.22">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-07-20T08:11:32-07:00">20 Jul 2023</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the first beta release of PHP 8.3.0, Beta 1. This continues the PHP 8.3 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php83">PHP Wiki</a>.</p><p>For source downloads of PHP 8.3.0 Beta 1 please visit the <a href="https://downloads.php.net/~eric">download page</a>.</p><p>Please carefully test this version and report any issues found in the <a href="https://github.com/php/php-src/issues">bug reporting system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.3.0beta1/NEWS">NEWS</a> file, or the <a href="https://github.com/php/php-src/blob/php-8.3.0beta1/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be Beta 2, planned for Aug 3 2023.</p><p>The signatures for the release can be found in <a href="https://gist.github.com/ericmann/5d3b2ddc1c8696510614d81690d4b347">the manifest</a> or on <a href="https://qa.php.net/">the QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-07-06T14:45:21+00:00">06 Jul 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.1.21. This is a bug fix release.</p><p>All PHP 8.1 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.1.21 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.1.21">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-07-06T09:47:01+00:00">06 Jul 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.8. This is a bug fix release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.8 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.8">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-07-06T09:43:06+00:00">06 Jul 2023</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the third testing release of PHP 8.3.0, Alpha 3. This continues the PHP 8.3 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php83">PHP Wiki</a>.</p><p>For source downloads of PHP 8.3.0 Alpha 3 please visit the <a href="https://downloads.php.net/~jakub/">download page</a>.</p><p>Please carefully test this version and report any issues found in the <a href="https://github.com/php/php-src/issues">bug reporting system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.3.0alpha3/NEWS">NEWS</a> file, or the <a href="https://github.com/php/php-src/blob/php-8.3.0alpha3/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be Beta 1, planned for 20 Jul 2023.</p><p>The signatures for the release can be found in the <a href="https://gist.github.com/bukka/9324ba069ce9588c5000a60fbb8cccbb">manifest</a> or on the <a href="https://qa.php.net/">QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-06-22T11:15:33-07:00">22 Jun 2023</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the second testing release of PHP 8.3.0, Alpha 2. This continues the PHP 8.3 release cycle, the rouch outline of which is specified in the <a href="https://wiki.php.net/todo/php83">PHP Wiki</a>.</p><p>For source downloads of PHP 8.3.0 Alpha 2 please visit <a href="https://downloads.php.net/~eric/">download page</a>.</p><p>Please carefully test this version and report any issues found in the <a href="https://github.com/php/php-src/issues">bug reporting system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.3.0alpha2/NEWS">NEWS</a> file, or the <a href="https://github.com/php/php-src/blob/php-8.3.0alpha2/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be Alpha 3, planned for 6 July 2023.</p><p>The signatures for this release can be found in <a href="https://gist.github.com/ericmann/7355303dbb2d350522b155349c61fc7c">the manifest</a> or on <a href="https://qa.php.net/">the QA site</a>.</p><p>Thank you for helping us make PHP better!</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-06-08T18:24:16+00:00">08 Jun 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.1.20. This is a security release.</p><p>All PHP 8.1 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.1.20 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.1.20">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-06-08T18:14:14+00:00">08 Jun 2023</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the first testing release of PHP 8.3.0, Alpha 1. This starts the PHP 8.3 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php83">PHP Wiki</a>.</p><p>For source downloads of PHP 8.3.0 Alpha 1 please visit the <a href="https://downloads.php.net/~jakub/">download page</a>.</p><p>Please carefully test this version and report any issues found using <a href="https://github.com/php/php-src/issues">the bug tracking system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.3.0alpha1/NEWS">NEWS</a> file, or the <a href="https://github.com/php/php-src/blob/php-8.3.0alpha1/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be Alpha 2, planned for 22 Jun 2023.</p><p>The signatures for the release can be found in the <a href="https://gist.github.com/bukka/66530718f180092527a741d023492b23">manifest</a> or on the <a href="https://qa.php.net/">QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-06-08T16:50:22+00:00">08 Jun 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.7. This is a security release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.7 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.7">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-06-08T09:03:22+00:00">08 Jun 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.0.29. This is a security release.</p><p>All PHP 8.0 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.0.29 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/#php-8.0">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.0.29">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-05-11T23:40:59+00:00">11 May 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.1.19. This is a bug fix release.</p><p>All PHP 8.1 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.1.19 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.1.19">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-05-11T10:08:59+00:00">11 May 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.6. This is a bug fix release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.6 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.6">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-04-13T23:59:59+00:00">13 Apr 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.1.18. This is a bug fix release.</p><p>All PHP 8.1 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.1.18 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.1.18">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-04-13T15:24:07+00:00">13 Apr 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.5. This is a bug fix release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.5 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.5">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-03-16T13:18:09+00:00">16 Mar 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.4. This is a bug fix release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.4 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.4">ChangeLog</a>.</p></div></article></div></section><aside class="tips"><div class="inner"><p class="panel"><a href="https://www.php.net/cal.php">User Group Events</a></p><p class="panel"><a href="https://www.php.net/thanks.php">Special Thanks</a></p></div>
</aside></div>]]></description>
      <link>https://www.php.net/index.php#2023-09-28-2</link>
      <guid>https://www.php.net/index.php#2023-09-28-2</guid>
      <pubDate>Thu, 28 Sep 2023 02:00:00 +0200</pubDate>
    </item>
    <item>
      <title><![CDATA[PHP 8.3.0 RC 2 available for testing - PHP: Hypertext Preprocessor]]></title>
      <description><![CDATA[<div id="intro" class="clearfix container hero"><img class="hero-logo" src="https://www.php.net/images/logos/php-logo-white.svg" alt="php" width="240" height="120" /><p class="hero-text">A <strong>popular general-purpose scripting language</strong> that is especially suited to web development.Fast, flexible and pragmatic, PHP powers everything from your blog to the most popular websites in the world.</p><p><a href="https://www.php.net/releases/8.2/index.php" class="hero-btn hero-btn-primary">What's new in 8.2</a> <a href="https://www.php.net/downloads.php" class="hero-btn hero-btn-secondary">Download</a></p><ul class="hero-versions"><li class="hero-version"><a class="hero-version-link" href="https://www.php.net/downloads.php#v8.2.10">8.2.10</a> · <a class="notes" href="https://www.php.net/ChangeLog-8.php#8.2.10">Changelog</a> · <a class="notes" href="https://www.php.net/migration82">Upgrading</a></li>
<li class="hero-version"><a class="hero-version-link" href="https://www.php.net/downloads.php#v8.1.23">8.1.23</a> · <a class="notes" href="https://www.php.net/ChangeLog-8.php#8.1.23">Changelog</a> · <a class="notes" href="https://www.php.net/migration81">Upgrading</a></li>
<li class="hero-version"><a class="hero-version-link" href="https://www.php.net/downloads.php#v8.0.30">8.0.30</a> · <a class="notes" href="https://www.php.net/ChangeLog-8.php#8.0.30">Changelog</a> · <a class="notes" href="https://www.php.net/migration80">Upgrading</a></li>
</ul></div><div id="layout" class="clearfix"><section id="layout-content"><div class="home-content"><article class="newsentry"><header class="title"><time datetime="2023-09-14T03:51:40-07:00">14 Sep 2023</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the release of PHP 8.3.0, RC 2. This is the second release candidate, continuing the PHP 8.3 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php83">PHP Wiki</a>.</p><p>For source downloads of PHP 8.3.0, RC 2 please visit the <a href="https://downloads.php.net/~eric/">download page</a>.</p><p>Please carefully test this version and report any issues found in the <a href="http://bugs.php.net">bug reporting system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.3.0RC2/NEWS">NEWS</a> file or the <a href="https://github.com/php/php-src/blob/php-8.3.0RC2/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be the third release candidate (RC 3), planned for 28 September 2023.</p><p>The signatures for the release can be found in <a href="https://gist.github.com/ericmann/d8c56e1244679ab41672dcfdbea2b0a6">the manifest</a> or on <a href="https://qa.php.net/">the QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-08-31T16:37:56+00:00">31 Aug 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.1.23. This is a bug fix release.</p><p>All PHP 8.1 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.1.23 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.1.23">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-08-31T16:15:39+00:00">31 Aug 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.10. This is a bug fix release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.10 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.10">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-08-31T11:23:53+00:00">31 Aug 2023</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the release of PHP 8.3.0, RC 1. This is the first release candidate, continuing the PHP 8.3 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php83">PHP Wiki</a>.</p><p>For source downloads of PHP 8.3.0, RC 1 please visit the <a href="https://downloads.php.net/~jakub/">download page</a>.</p><p>Please carefully test this version and report any issues found in the <a href="http://bugs.php.net">bug reporting system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.3.0RC1/NEWS">NEWS</a> file or the <a href="https://github.com/php/php-src/blob/php-8.3.0RC1/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be the second release candidate (RC 2), planned for 14 September 2023.</p><p>The signatures for the release can be found in <a href="https://gist.github.com/bukka/b5d4f8f27d1f013837e1f596d90ea1fc">the manifest</a> or on <a href="https://qa.php.net/">the QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-08-17T07:26:35-07:00">17 Aug 2023</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the third beta release of PHP 8.3.0, Beta 3. This continues the PHP 8.3 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php83">PHP Wiki</a>.</p><p>For source downloads of PHP 8.3.0 Beta 3 please visit the <a href="https://downloads.php.net/~eric">download page</a>.</p><p>Please carefully test this version and report any issues found in the <a href="https://github.com/php/php-src/issues">bug reporting system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.3.0beta3/NEWS">NEWS</a> file, or the <a href="https://github.com/php/php-src/blob/php-8.3.0beta3/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be RC 1, planned for Aug 31 2023.</p><p>The signatures for the release can be found in <a href="https://gist.github.com/ericmann/8ea0c14efef9b0e0a7e4222e06ed5097">the manifest</a> or on <a href="https://qa.php.net/">the QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-08-16T18:06:57+00:00">16 Aug 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.9. This is a security release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p><strong>Windows source and binaries are not synchronized and do not contain a fix for GH-11854.</strong></p><p>For source downloads of PHP 8.2.9 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.9">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-08-04T18:29:29+00:00">04 Aug 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.0.30. This is a security release.</p><p>All PHP 8.0 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.0.30 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.0.30">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-08-03T11:50:26-07:00">03 Aug 2023</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the second beta release of PHP 8.3.0, Beta 2. This continues the PHP 8.3 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php83">PHP Wiki</a>.</p><p>For source downloads of PHP 8.3.0 Beta 2 please visit the <a href="https://downloads.php.net/~jakub">download page</a>.</p><p>Please carefully test this version and report any issues found in the <a href="https://github.com/php/php-src/issues">bug reporting system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.3.0beta2/NEWS">NEWS</a> file, or the <a href="https://github.com/php/php-src/blob/php-8.3.0beta2/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be Beta 3, planned for Aug 17 2023.</p><p>The signatures for the release can be found in <a href="https://gist.github.com/bukka/31646ada5b94b4d2b78e0551905f5745">the manifest</a> or on <a href="https://qa.php.net/">the QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-08-03T15:07:49+00:00">03 Aug 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.1.22. This is a security release.</p><p>All PHP 8.1 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.1.22 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.1.22">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-07-20T08:11:32-07:00">20 Jul 2023</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the first beta release of PHP 8.3.0, Beta 1. This continues the PHP 8.3 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php83">PHP Wiki</a>.</p><p>For source downloads of PHP 8.3.0 Beta 1 please visit the <a href="https://downloads.php.net/~eric">download page</a>.</p><p>Please carefully test this version and report any issues found in the <a href="https://github.com/php/php-src/issues">bug reporting system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.3.0beta1/NEWS">NEWS</a> file, or the <a href="https://github.com/php/php-src/blob/php-8.3.0beta1/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be Beta 2, planned for Aug 3 2023.</p><p>The signatures for the release can be found in <a href="https://gist.github.com/ericmann/5d3b2ddc1c8696510614d81690d4b347">the manifest</a> or on <a href="https://qa.php.net/">the QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-07-06T14:45:21+00:00">06 Jul 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.1.21. This is a bug fix release.</p><p>All PHP 8.1 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.1.21 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.1.21">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-07-06T09:47:01+00:00">06 Jul 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.8. This is a bug fix release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.8 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.8">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-07-06T09:43:06+00:00">06 Jul 2023</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the third testing release of PHP 8.3.0, Alpha 3. This continues the PHP 8.3 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php83">PHP Wiki</a>.</p><p>For source downloads of PHP 8.3.0 Alpha 3 please visit the <a href="https://downloads.php.net/~jakub/">download page</a>.</p><p>Please carefully test this version and report any issues found in the <a href="https://github.com/php/php-src/issues">bug reporting system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.3.0alpha3/NEWS">NEWS</a> file, or the <a href="https://github.com/php/php-src/blob/php-8.3.0alpha3/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be Beta 1, planned for 20 Jul 2023.</p><p>The signatures for the release can be found in the <a href="https://gist.github.com/bukka/9324ba069ce9588c5000a60fbb8cccbb">manifest</a> or on the <a href="https://qa.php.net/">QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-06-22T11:15:33-07:00">22 Jun 2023</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the second testing release of PHP 8.3.0, Alpha 2. This continues the PHP 8.3 release cycle, the rouch outline of which is specified in the <a href="https://wiki.php.net/todo/php83">PHP Wiki</a>.</p><p>For source downloads of PHP 8.3.0 Alpha 2 please visit <a href="https://downloads.php.net/~eric/">download page</a>.</p><p>Please carefully test this version and report any issues found in the <a href="https://github.com/php/php-src/issues">bug reporting system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.3.0alpha2/NEWS">NEWS</a> file, or the <a href="https://github.com/php/php-src/blob/php-8.3.0alpha2/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be Alpha 3, planned for 6 July 2023.</p><p>The signatures for this release can be found in <a href="https://gist.github.com/ericmann/7355303dbb2d350522b155349c61fc7c">the manifest</a> or on <a href="https://qa.php.net/">the QA site</a>.</p><p>Thank you for helping us make PHP better!</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-06-08T18:24:16+00:00">08 Jun 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.1.20. This is a security release.</p><p>All PHP 8.1 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.1.20 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.1.20">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-06-08T18:14:14+00:00">08 Jun 2023</time>
</header><div class="newscontent"><p>The PHP team is pleased to announce the first testing release of PHP 8.3.0, Alpha 1. This starts the PHP 8.3 release cycle, the rough outline of which is specified in the <a href="https://wiki.php.net/todo/php83">PHP Wiki</a>.</p><p>For source downloads of PHP 8.3.0 Alpha 1 please visit the <a href="https://downloads.php.net/~jakub/">download page</a>.</p><p>Please carefully test this version and report any issues found using <a href="https://github.com/php/php-src/issues">the bug tracking system</a>.</p><p><strong>Please DO NOT use this version in production, it is an early test version.</strong></p><p>For more information on the new features and other changes, you can read the <a href="https://github.com/php/php-src/blob/php-8.3.0alpha1/NEWS">NEWS</a> file, or the <a href="https://github.com/php/php-src/blob/php-8.3.0alpha1/UPGRADING">UPGRADING</a> file for a complete list of upgrading notes. These files can also be found in the release archive.</p><p>The next release will be Alpha 2, planned for 22 Jun 2023.</p><p>The signatures for the release can be found in the <a href="https://gist.github.com/bukka/66530718f180092527a741d023492b23">manifest</a> or on the <a href="https://qa.php.net/">QA site</a>.</p><p>Thank you for helping us make PHP better.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-06-08T16:50:22+00:00">08 Jun 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.7. This is a security release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.7 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.7">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-06-08T09:03:22+00:00">08 Jun 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.0.29. This is a security release.</p><p>All PHP 8.0 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.0.29 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/#php-8.0">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.0.29">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-05-11T23:40:59+00:00">11 May 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.1.19. This is a bug fix release.</p><p>All PHP 8.1 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.1.19 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.1.19">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-05-11T10:08:59+00:00">11 May 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.6. This is a bug fix release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.6 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.6">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-04-13T23:59:59+00:00">13 Apr 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.1.18. This is a bug fix release.</p><p>All PHP 8.1 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.1.18 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.1.18">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-04-13T15:24:07+00:00">13 Apr 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.5. This is a bug fix release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.5 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.5">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-03-16T13:18:09+00:00">16 Mar 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.2.4. This is a bug fix release.</p><p>All PHP 8.2 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.2.4 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.2.4">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-03-16T12:01:57+00:00">16 Mar 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.1.17. This is a bug fix release.</p><p>All PHP 8.1 users are encouraged to upgrade to this version.</p><p>For source downloads of PHP 8.1.17 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.1.17">ChangeLog</a>.</p></div></article><article class="newsentry"><header class="title"><time datetime="2023-02-14T17:50:17+00:00">14 Feb 2023</time>
</header><div class="newscontent"><p>The PHP development team announces the immediate availability of PHP 8.1.16. This is a security release that addresses CVE-2023-0567, CVE-2023-0568, and CVE-2023-0662.</p><p>All PHP 8.1 users are advised to upgrade to this version.</p><p>For source downloads of PHP 8.1.16 please visit our <a href="https://www.php.net/downloads.php">downloads page</a>, Windows source and binaries can be found on <a href="https://windows.php.net/download/">windows.php.net/download/</a>. The list of changes is recorded in the <a href="https://www.php.net/ChangeLog-8.php#8.1.16">ChangeLog</a>.</p></div></article></div></section><aside class="tips"><div class="inner"><p class="panel"><a href="https://www.php.net/cal.php">User Group Events</a></p><p class="panel"><a href="https://www.php.net/thanks.php">Special Thanks</a></p></div>
</aside></div>]]></description>
      <link>https://www.php.net/index.php#2023-09-14-1</link>
      <guid>https://www.php.net/index.php#2023-09-14-1</guid>
      <pubDate>Thu, 14 Sep 2023 02:00:00 +0200</pubDate>
    </item>
    <item>
      <title><![CDATA[Xdebug Update: August 2023 - Derick Rethans]]></title>
      <description><![CDATA[<p>In this monthly update I explain what happened with Xdebug development in the past month. These are normally published on the first Tuesday on or after the 5th of each month.</p><p><a href="https://www.patreon.com/derickr">Patreon</a> and <a href="https://github.com/sponsors/derickr/">GitHub</a> supporters will get it earlier, around the first of each month.</p><p>You can <a href="https://www.patreon.com/bePatron?u=7864328">become a patron</a> or support me through <a href="https://github.com/sponsors/derickr">GitHub Sponsors</a>. I am currently 36% towards my $2,500 per month goal, which is set to allow continued maintenance of Xdebug.</p><p>If you are leading a team or company, then it is also possible to support Xdebug through <a href="https://xdebug.org/support">a subscription</a>.</p><p>In the last month, I spend around 27 hours on Xdebug, with 32 hours funded.</p><div class="articleSubSection"><h2>Towards Xdebug 3.3</h2><p>In August I mostly spend my time on improving Xdebug's xdebug_get_function_stack() function and stack traces with regard to chained exceptions.</p><p>A <a href="https://bugs.xdebug.org/1562">feature request</a> asked whether it would be possible to add the local variables for each stack frame that is returned with the xdebug_get_function_stack() function. Xdebug can already show local variables for the top most frame when it shows stack traces (through the <a href="http://xdebug.org/docs/all_settings#show_local_vars">xdebug.show_local_vars</a> setting), but the function's result don't include them.</p><p>When implementing this feature, I noticed that arguments were being returned as strings, instead of actual values, as part of each stack frame. I created <a href="https://bugs.xdebug.org/2194">an issue</a> for that and implemented that as well.</p><p>When the original requester tried out the new feature, it turned out that he wanted to do this in a user-defined exception handler. However, at that stage, the original stack has been destroyed, and Xdebug no longer could access that information.</p><p>To work around this, I now cache the stack when an exception gets <strong>thrown</strong> so that the cached version then can be requested when calling <code>xdebug_get_function_stack()</code> with the new <code>from_exception</code> option.</p><p>That looks like:</p><pre>&lt;?php
class Handlers
{
    function __construct(private string $title, private float $PIE) {}
    static function exceptionHandler($exception)
    {
        $s = xdebug_get_function_stack( [ 'from_exception' =&gt; $exception ] );
        var_dump($s);
    }
}
class Error_Entry
{
    public function __construct($base, $errno)
    {
        throw new Exception();
    }
}
set_exception_handler(['Handlers', 'exceptionHandler']);
$e = new Error_Entry(1, 2);
?&gt;
</pre><p>Xdebug's cache is eight items big, which allows for 8 rethrown/chained exception stacks to be remembered.</p><p>Because of this cache it was now also (finally) possible to resolve <a href="https://bugs.xdebug.org/450">issue #450</a> and <a href="https://bugs.xdebug.org/476">issue #476</a>. This now means that chained and rethrown exceptions are now displayed when Xdebug shows a stack trace, whether it is on the CLI, or in an HTML context.</p><p>Over the next few months I will continue to work on the features and issues on the <a href="https://bugs.xdebug.org/roadmap_page.php?version_id=101">3.3 roadmap</a>, without any guarantees these tickets will be implemented.</p><p>If you have comments, suggestions, or if your company wants to help fund features, please <a href="mailto:derick@xdebug.org">reach out</a>, or leave comments on the document.</p></div><div class="articleSubSection"><h2>Xdebug Videos</h2><p>I have published one new videos in the last month:</p><ul><li>
<p><a href="https://www.youtube.com/watch?v=u420A89tIMY">PHP: Debugging FFI and PHP</a></p>
</li>
</ul><p>Let me know what you'd like to see!</p><p>You can find all previous videos on my <a href="https://www.youtube.com/playlist?list=PLg9Kjjye-m1g_eXpdaifUqLqALLqZqKd4">YouTube channel</a>.</p></div><div class="articleSubSection"><h2>Business Supporter Scheme and Funding</h2><p>In the last few months, two new business supporters signed up:</p><p><a href="https://rewe-digital.com">REWE Digital GmbH</a> through the Supporter Scheme, and <a href="https://www.clever-age.com/en/">Clever Age</a> on Patreon.</p><p>If you, or your company, would also like to support Xdebug, head over to the <a href="https://xdebug.org/support">support</a> page!</p><p>Besides business support, I also maintain a <a href="https://www.patreon.com/derickr">Patreon</a> page, a profile on <a href="https://github.com/sponsors/derickr">GitHub sponsors</a>, as well as an <a href="https://opencollective.com/xdebug">OpenCollective</a> organisation.</p></div><div class="articleSubSection"><h2>Xdebug Cloud</h2><p>Xdebug Cloud is the <em>Proxy As A Service</em> platform to allow for debugging in more scenarios, where it is hard, or impossible, to have Xdebug make a connection to the IDE. It is continuing to operate as Beta release.</p><p>Packages start at £49/month, and I have recently introduced a package for larger companies. This has a larger initial set of tokens, and discounted extra tokens.</p><p>If you want to be kept up to date with Xdebug Cloud, please sign up to the <a href="https://xdebug.cloud/newsletter">mailinglist</a>, which I will use to send out an update not more than once a month.</p></div>]]></description>
      <link>https://derickrethans.nl/xdebug-update-august-2023.html</link>
      <guid>https://derickrethans.nl/xdebug-update-august-2023.html</guid>
      <pubDate>Tue, 12 Sep 2023 10:27:00 +0200</pubDate>
    </item>
  </channel>
</rss>
