<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>PHP &#8211; Aimeos</title>
	<atom:link href="https://aimeos.org/tips/category/php/feed/" rel="self" type="application/rss+xml" />
	<link>https://aimeos.org/tips</link>
	<description>ultra fast PHP e-commerce framework</description>
	<lastBuildDate>Thu, 05 May 2022 09:03:42 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=5.7.8</generator>

<image>
	<url>https://aimeos.org/tips/wp-content/uploads/2019/09/Aimeos_e_200-100x104.png</url>
	<title>PHP &#8211; Aimeos</title>
	<link>https://aimeos.org/tips</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Aimeos 2022 news</title>
		<link>https://aimeos.org/tips/aimeos-2022-news/</link>
					<comments>https://aimeos.org/tips/aimeos-2022-news/#respond</comments>
		
		<dc:creator><![CDATA[aimeos]]></dc:creator>
		<pubDate>Thu, 10 Feb 2022 08:46:24 +0000</pubDate>
				<category><![CDATA[Laravel]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Releases]]></category>
		<category><![CDATA[TYPO3]]></category>
		<guid isPermaLink="false">https://aimeos.org/tips/?p=896</guid>

					<description><![CDATA[Since 2022.01 beta, the Aimeos core is using Upscheme for updating the database schema and migrating data between new releases. Upscheme is composer package for schema management based on Doctrine DBAL which offers an easy to use API. You can<span class="ellipsis">&#8230;</span><div class="read-more"><a href="https://aimeos.org/tips/aimeos-2022-news/">Read more <span class="screen-reader-text">Aimeos 2022 news</span><span class="meta-nav"> &#8250;</span></a></div><!-- end of .read-more -->]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-image size-full"><a href="https://aimeos.org/tips/wp-content/uploads/2021/10/aimeos-release-rect-big.jpg"><img width="1200" height="630" src="https://aimeos.org/tips/wp-content/uploads/2021/10/aimeos-release-rect-big.jpg" alt="" class="wp-image-887" srcset="https://aimeos.org/tips/wp-content/uploads/2021/10/aimeos-release-rect-big.jpg 1200w, https://aimeos.org/tips/wp-content/uploads/2021/10/aimeos-release-rect-big-300x158.jpg 300w, https://aimeos.org/tips/wp-content/uploads/2021/10/aimeos-release-rect-big-1024x538.jpg 1024w, https://aimeos.org/tips/wp-content/uploads/2021/10/aimeos-release-rect-big-768x403.jpg 768w, https://aimeos.org/tips/wp-content/uploads/2021/10/aimeos-release-rect-big-100x53.jpg 100w, https://aimeos.org/tips/wp-content/uploads/2021/10/aimeos-release-rect-big-150x79.jpg 150w, https://aimeos.org/tips/wp-content/uploads/2021/10/aimeos-release-rect-big-200x105.jpg 200w, https://aimeos.org/tips/wp-content/uploads/2021/10/aimeos-release-rect-big-450x236.jpg 450w, https://aimeos.org/tips/wp-content/uploads/2021/10/aimeos-release-rect-big-600x315.jpg 600w, https://aimeos.org/tips/wp-content/uploads/2021/10/aimeos-release-rect-big-900x473.jpg 900w" sizes="(max-width: 1200px) 100vw, 1200px" /></a></figure>



<p>Since 2022.01 beta, the Aimeos core is using <a href="https://upscheme.org">Upscheme</a> for updating the database schema and migrating data between new releases. Upscheme is composer package for schema management based on Doctrine DBAL which offers an easy to use API. You can also <a href="https://upscheme.org/#integrating-upscheme" data-type="URL" data-id="https://upscheme.org/#integrating-upscheme">integrate Upscheme it in your own application</a> easily and this article explains the differences and how you can write migrations with only a few lines of code <img src="https://s.w.org/images/core/emoji/13.0.1/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<span id="more-896"></span>



<h2>Why Upscheme</h2>



<p>Whenever you need to upgrade database schemas in more than one installation and your application supports more than one database (even MySQL and MariaDB differ in some details), you need a tool for schema management. And even if you only support one database vendor, it simplifies live because you don&#8217;t have to create messy custom scripts with raw SQL statements.</p>



<p>Aimeos used the Doctrine DBAL API directly up to 2021.10 LTS but DBAL has a very verbose API and requires a lot of code to do simple things. For example, creating/updating a table usually looks similar to these lines:</p>





<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="php"><pre class="de1"><span class="re0">$dbalManager</span> <span class="sy0">=</span> <span class="re0">$conn</span><span class="sy0">-&amp;</span>gt<span class="sy0">;</span>createSchemaManager<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
<span class="re0">$from</span> <span class="sy0">=</span> <span class="re0">$manager</span><span class="sy0">-&amp;</span>gt<span class="sy0">;</span>createSchema<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
<span class="re0">$to</span> <span class="sy0">=</span> <span class="re0">$manager</span><span class="sy0">-&amp;</span>gt<span class="sy0">;</span>createSchema<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
<span class="kw1">if</span><span class="br0">&#40;</span> <span class="re0">$to</span><span class="sy0">-&amp;</span>gt<span class="sy0">;</span>hasTable<span class="br0">&#40;</span> <span class="st_h">'test'</span> <span class="br0">&#41;</span> <span class="br0">&#41;</span> <span class="br0">&#123;</span>
	<span class="re0">$table</span> <span class="sy0">=</span> <span class="re0">$to</span><span class="sy0">-&amp;</span>gt<span class="sy0">;</span>getTable<span class="br0">&#40;</span> <span class="st_h">'test'</span> <span class="br0">&#41;</span><span class="sy0">;</span>
<span class="br0">&#125;</span> <span class="kw1">else</span> <span class="br0">&#123;</span>
	<span class="re0">$table</span> <span class="sy0">=</span> <span class="re0">$to</span><span class="sy0">-&amp;</span>gt<span class="sy0">;</span>createTable<span class="br0">&#40;</span> <span class="st_h">'test'</span> <span class="br0">&#41;</span><span class="sy0">;</span>
<span class="br0">&#125;</span>
&nbsp;
<span class="re0">$table</span><span class="sy0">-&amp;</span>gt<span class="sy0">;</span>addOption<span class="br0">&#40;</span> <span class="st_h">'engine'</span><span class="sy0">,</span> <span class="st_h">'InnoDB'</span> <span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
<span class="re0">$table</span><span class="sy0">-&amp;</span>gt<span class="sy0">;</span>addColumn<span class="br0">&#40;</span> <span class="st_h">'id'</span><span class="sy0">,</span> <span class="st_h">'integer'</span><span class="sy0">,</span> <span class="br0">&#91;</span><span class="st_h">'autoincrement'</span> <span class="sy0">=&amp;</span>gt<span class="sy0">;</span> <span class="kw4">true</span><span class="br0">&#93;</span> <span class="br0">&#41;</span><span class="sy0">;</span>
<span class="re0">$table</span><span class="sy0">-&amp;</span>gt<span class="sy0">;</span>addColumn<span class="br0">&#40;</span> <span class="st_h">'domain'</span><span class="sy0">,</span> <span class="st_h">'string'</span><span class="sy0">,</span> <span class="br0">&#91;</span><span class="st_h">'length'</span> <span class="sy0">=&amp;</span>gt<span class="sy0">;</span> <span class="nu0">32</span><span class="br0">&#93;</span> <span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
<span class="kw1">if</span><span class="br0">&#40;</span> <span class="re0">$conn</span><span class="sy0">-&amp;</span>gt<span class="sy0">;</span>getDatabasePlatform<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">-&amp;</span>gt<span class="sy0">;</span>getName<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="sy0">===</span> <span class="st_h">'mysql'</span> <span class="br0">&#41;</span> <span class="br0">&#123;</span>
	<span class="re0">$table</span><span class="sy0">-&amp;</span>gt<span class="sy0">;</span>addColumn<span class="br0">&#40;</span> <span class="st_h">'code'</span><span class="sy0">,</span> <span class="st_h">'string'</span><span class="sy0">,</span> <span class="br0">&#91;</span><span class="st_h">'length'</span> <span class="sy0">=&amp;</span>gt<span class="sy0">;</span> <span class="nu0">64</span><span class="sy0">,</span> <span class="st_h">'customSchemaOptions'</span> <span class="sy0">=&amp;</span>gt<span class="sy0">;</span> <span class="br0">&#91;</span><span class="st_h">'charset'</span> <span class="sy0">=&amp;</span>gt<span class="sy0">;</span> <span class="st_h">'binary'</span><span class="br0">&#93;</span><span class="br0">&#93;</span> <span class="br0">&#41;</span><span class="sy0">;</span>
<span class="br0">&#125;</span> <span class="kw1">else</span> <span class="br0">&#123;</span>
	<span class="re0">$table</span><span class="sy0">-&amp;</span>gt<span class="sy0">;</span>addColumn<span class="br0">&#40;</span> <span class="st_h">'code'</span><span class="sy0">,</span> <span class="st_h">'string'</span><span class="sy0">,</span> <span class="br0">&#91;</span><span class="st_h">'length'</span> <span class="sy0">=&amp;</span>gt<span class="sy0">;</span> <span class="nu0">64</span><span class="br0">&#93;</span><span class="br0">&#93;</span> <span class="br0">&#41;</span><span class="sy0">;</span>
<span class="br0">&#125;</span>
&nbsp;
<span class="re0">$table</span><span class="sy0">-&amp;</span>gt<span class="sy0">;</span>addColumn<span class="br0">&#40;</span> <span class="st_h">'label'</span><span class="sy0">,</span> <span class="st_h">'string'</span><span class="sy0">,</span> <span class="br0">&#91;</span><span class="st_h">'length'</span> <span class="sy0">=&amp;</span>gt<span class="sy0">;</span> <span class="nu0">255</span><span class="br0">&#93;</span> <span class="br0">&#41;</span><span class="sy0">;</span>
<span class="re0">$table</span><span class="sy0">-&amp;</span>gt<span class="sy0">;</span>addColumn<span class="br0">&#40;</span> <span class="st_h">'pos'</span><span class="sy0">,</span> <span class="st_h">'integer'</span><span class="sy0">,</span> <span class="br0">&#91;</span><span class="st_h">'default'</span> <span class="sy0">=&amp;</span>gt<span class="sy0">;</span> <span class="nu0">0</span><span class="br0">&#93;</span> <span class="br0">&#41;</span><span class="sy0">;</span>
<span class="re0">$table</span><span class="sy0">-&amp;</span>gt<span class="sy0">;</span>addColumn<span class="br0">&#40;</span> <span class="st_h">'status'</span><span class="sy0">,</span> <span class="st_h">'smallint'</span><span class="sy0">,</span> <span class="br0">&#91;</span><span class="br0">&#93;</span> <span class="br0">&#41;</span><span class="sy0">;</span>
<span class="re0">$table</span><span class="sy0">-&amp;</span>gt<span class="sy0">;</span>addColumn<span class="br0">&#40;</span> <span class="st_h">'mtime'</span><span class="sy0">,</span> <span class="st_h">'datetime'</span><span class="sy0">,</span> <span class="br0">&#91;</span><span class="br0">&#93;</span> <span class="br0">&#41;</span><span class="sy0">;</span>
<span class="re0">$table</span><span class="sy0">-&amp;</span>gt<span class="sy0">;</span>addColumn<span class="br0">&#40;</span> <span class="st_h">'ctime'</span><span class="sy0">,</span> <span class="st_h">'datetime'</span><span class="sy0">,</span> <span class="br0">&#91;</span><span class="br0">&#93;</span> <span class="br0">&#41;</span><span class="sy0">;</span>
<span class="re0">$table</span><span class="sy0">-&amp;</span>gt<span class="sy0">;</span>addColumn<span class="br0">&#40;</span> <span class="st_h">'editor'</span><span class="sy0">,</span> <span class="st_h">'string'</span><span class="sy0">,</span> <span class="br0">&#91;</span><span class="st_h">'length'</span> <span class="sy0">=&amp;</span>gt<span class="sy0">;</span> <span class="nu0">255</span><span class="br0">&#93;</span> <span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
<span class="re0">$table</span><span class="sy0">-&amp;</span>gt<span class="sy0">;</span>setPrimaryKey<span class="br0">&#40;</span> <span class="br0">&#91;</span><span class="st_h">'id'</span><span class="br0">&#93;</span> <span class="br0">&#41;</span><span class="sy0">;</span>
<span class="re0">$table</span><span class="sy0">-&amp;</span>gt<span class="sy0">;</span>addUniqueIndex<span class="br0">&#40;</span> <span class="br0">&#91;</span><span class="st_h">'domain'</span><span class="sy0">,</span> <span class="st_h">'code'</span><span class="br0">&#93;</span> <span class="br0">&#41;</span><span class="sy0">;</span>
<span class="re0">$table</span><span class="sy0">-&amp;</span>gt<span class="sy0">;</span>addIndex<span class="br0">&#40;</span> <span class="br0">&#91;</span><span class="st_h">'status'</span><span class="sy0">,</span> <span class="st_h">'pos'</span><span class="br0">&#93;</span> <span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
<span class="kw1">foreach</span><span class="br0">&#40;</span> <span class="re0">$from</span><span class="sy0">-&amp;</span>gt<span class="sy0">;</span>getMigrateToSql<span class="br0">&#40;</span> <span class="re0">$to</span><span class="sy0">,</span> <span class="re0">$conn</span><span class="sy0">-&amp;</span>gt<span class="sy0">;</span>getDatabasePlatform<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#41;</span> <span class="kw1">as</span> <span class="re0">$sql</span> <span class="br0">&#41;</span> <span class="br0">&#123;</span>
	<span class="re0">$conn</span><span class="sy0">-&amp;</span>gt<span class="sy0">;</span>executeStatement<span class="br0">&#40;</span> <span class="re0">$sql</span> <span class="br0">&#41;</span><span class="sy0">;</span>
<span class="br0">&#125;</span></pre></div></div></div></div></div></div></div>






<p>Contrary, Upscheme offers a very terse API which does the same in only a few lines of code:</p>





<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="php"><pre class="de1"><span class="re0">$this</span><span class="sy0">-&amp;</span>gt<span class="sy0">;</span>db<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">-&amp;</span>gt<span class="sy0">;</span>table<span class="br0">&#40;</span> <span class="st_h">'test'</span><span class="sy0">,</span> <span class="kw2">function</span><span class="br0">&#40;</span> <span class="re0">$t</span> <span class="br0">&#41;</span> <span class="br0">&#123;</span>
	<span class="re0">$t</span><span class="sy0">-&amp;</span>gt<span class="sy0">;</span>engine <span class="sy0">=</span> <span class="st_h">'InnoDB'</span><span class="sy0">;</span>
&nbsp;
	<span class="re0">$t</span><span class="sy0">-&amp;</span>gt<span class="sy0">;</span>id<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
	<span class="re0">$t</span><span class="sy0">-&amp;</span>gt<span class="sy0">;</span>string<span class="br0">&#40;</span> <span class="st_h">'domain'</span><span class="sy0">,</span> <span class="nu0">32</span> <span class="br0">&#41;</span><span class="sy0">;</span>
	<span class="re0">$t</span><span class="sy0">-&amp;</span>gt<span class="sy0">;</span>string<span class="br0">&#40;</span> <span class="st_h">'code'</span><span class="sy0">,</span> <span class="nu0">64</span> <span class="br0">&#41;</span><span class="sy0">-&amp;</span>gt<span class="sy0">;</span>opt<span class="br0">&#40;</span> <span class="st_h">'charset'</span><span class="sy0">,</span> <span class="st_h">'binary'</span><span class="sy0">,</span> <span class="st_h">'mysql'</span> <span class="br0">&#41;</span><span class="sy0">;</span>
	<span class="re0">$t</span><span class="sy0">-&amp;</span>gt<span class="sy0">;</span>string<span class="br0">&#40;</span> <span class="st_h">'label'</span><span class="sy0">,</span> <span class="nu0">255</span> <span class="br0">&#41;</span><span class="sy0">;</span>
	<span class="re0">$t</span><span class="sy0">-&amp;</span>gt<span class="sy0">;</span>int<span class="br0">&#40;</span> <span class="st_h">'pos'</span> <span class="br0">&#41;</span><span class="sy0">-&amp;</span>gt<span class="sy0">;</span><span class="kw1">default</span><span class="br0">&#40;</span> <span class="nu0">0</span> <span class="br0">&#41;</span><span class="sy0">;</span>
	<span class="re0">$t</span><span class="sy0">-&amp;</span>gt<span class="sy0">;</span>smallint<span class="br0">&#40;</span> <span class="st_h">'status'</span> <span class="br0">&#41;</span><span class="sy0">;</span>
	<span class="re0">$t</span><span class="sy0">-&amp;</span>gt<span class="sy0">;</span>meta<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
	<span class="re0">$t</span><span class="sy0">-&amp;</span>gt<span class="sy0">;</span>unique<span class="br0">&#40;</span> <span class="br0">&#91;</span><span class="st_h">'domain'</span><span class="sy0">,</span> <span class="st_h">'code'</span><span class="br0">&#93;</span> <span class="br0">&#41;</span><span class="sy0">;</span>
	<span class="re0">$t</span><span class="sy0">-&amp;</span>gt<span class="sy0">;</span>index<span class="br0">&#40;</span> <span class="br0">&#91;</span><span class="st_h">'status'</span><span class="sy0">,</span> <span class="st_h">'pos'</span><span class="br0">&#93;</span> <span class="br0">&#41;</span><span class="sy0">;</span>
<span class="br0">&#125;</span> <span class="br0">&#41;</span><span class="sy0">;</span></pre></div></div></div></div></div></div></div>






<p>Upscheme also offers much better support for migrating data. Instead of using a &#8220;migration&#8221; table to keep track executed migrations which can get out of sync, Upscheme checks the current state of the schema and applies only necessary changes to update the tables, columns and other schema objects.</p>



<p>If your application allows 3rd party plugins you will love <a href="https://upscheme.org/#dependencies">Upscheme&#8217;s dependency management</a> based on tasks that must run before or after the current one. Thus, extensions can modify existing tables and migrate data without interfering with core tasks.</p>



<h2>Create/update database schema</h2>



<p>Creating and updating a table for example requires:</p>



<ul><li>an Upscheme task</li><li>the table definition</li></ul>



<p>The code below creates an Upscheme task named &#8220;Messages&#8221; by extending from the Upscheme base task and implements the <code>up()</code> method which is executed to perform the schema update:</p>





<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="php"><pre class="de1"><span class="kw2">namespace</span> Aimeos\Upscheme\Task<span class="sy0">;</span>
<span class="kw2">use</span> Aimeos\Upscheme\Schema\Table<span class="sy0">;</span>
&nbsp;
<span class="kw2">class</span> Messages <span class="kw2">extends</span> Base
<span class="br0">&#123;</span>
    <span class="kw2">public</span> <span class="kw2">function</span> up<span class="br0">&#40;</span><span class="br0">&#41;</span>
    <span class="br0">&#123;</span>
        <span class="re0">$this</span><span class="sy0">-&amp;</span>gt<span class="sy0">;</span>db<span class="br0">&#40;</span> <span class="st_h">'db-message'</span> <span class="br0">&#41;</span><span class="sy0">-&amp;</span>gt<span class="sy0">;</span>table<span class="br0">&#40;</span> <span class="st_h">'message'</span><span class="sy0">,</span> <span class="kw2">function</span><span class="br0">&#40;</span> Table <span class="re0">$t</span> <span class="br0">&#41;</span> <span class="br0">&#123;</span>
                <span class="re0">$t</span><span class="sy0">-&amp;</span>gt<span class="sy0">;</span>id<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
                <span class="re0">$t</span><span class="sy0">-&amp;</span>gt<span class="sy0">;</span>type<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
                <span class="re0">$t</span><span class="sy0">-&amp;</span>gt<span class="sy0">;</span>string<span class="br0">&#40;</span> <span class="st_h">'label'</span> <span class="br0">&#41;</span><span class="sy0">;</span>
                <span class="re0">$t</span><span class="sy0">-&amp;</span>gt<span class="sy0">;</span>bool<span class="br0">&#40;</span> <span class="st_h">'status'</span> <span class="br0">&#41;</span><span class="sy0">;</span>
                <span class="re0">$t</span><span class="sy0">-&amp;</span>gt<span class="sy0">;</span>meta<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
        <span class="br0">&#125;</span> <span class="br0">&#41;</span><span class="sy0">;</span>
    <span class="br0">&#125;</span>
<span class="br0">&#125;</span></pre></div></div></div></div></div></div></div>






<p>Within the <code>up()</code> method, the database schema for the &#8220;db-message&#8221; database is retrieved (with a fall-back to the standard database if &#8220;db-message&#8221; isn&#8217;t explicitely configured) and the &#8220;message&#8221; table defined. It consists of an &#8220;id&#8221; autoincrement integer column (with primary key), a label and status column as well as &#8220;ctime&#8221;, &#8220;mtime&#8221; and &#8220;editor&#8221; columns automatically added by the <code>meta()</code> function offered by the Aimeos core.</p>



<p>The <a href="https://upscheme.org/#tables">Table section in the Upscheme documentation</a> contains the list of pre-defined methods for creating the most often used column types. Nevertheless, you can always use the <a href="https://upscheme.org/#tablecol">Upscheme <code>col()</code> method</a> to create custom columns too and there&#8217;s also a <a href="https://upscheme.org/#column-modifiers">list of Upscheme column modifiers</a> to customize any column according to your needs.</p>



<p>Whenever you add, change or remove a column in your task, Upscheme will update your table schema automatically without any need to write an additional line of code!</p>



<h2>Migrate data</h2>



<p>Upscheme tasks can also migrate data between new releases and offers simple methods to <a href="https://upscheme.org/#dbinsert">insert</a>, <a href="https://upscheme.org/#dbupdate">update</a> and <a href="https://upscheme.org/#dbdelete">delete</a> records. Also, there are methods available to check for tables, columns and other schema object, to rename them and to drop them if they are not required any more:</p>





<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="php"><pre class="de1"><span class="re0">$this</span><span class="sy0">-&amp;</span>gt<span class="sy0">;</span>db<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">-&amp;</span>gt<span class="sy0">;</span>delete<span class="br0">&#40;</span>
    <span class="st_h">'message'</span><span class="sy0">,</span>
    <span class="br0">&#91;</span><span class="st_h">'type'</span> <span class="sy0">=&amp;</span>gt<span class="sy0">;</span> <span class="st_h">'custom'</span><span class="br0">&#93;</span>
<span class="br0">&#41;</span><span class="sy0">-&amp;</span>gt<span class="sy0">;</span>dropColumn<span class="br0">&#40;</span>
    <span class="st_h">'message'</span><span class="sy0">,</span>
    <span class="st_h">'type'</span>
<span class="br0">&#41;</span><span class="sy0">-&amp;</span>gt<span class="sy0">;</span>update<span class="br0">&#40;</span>
    <span class="st_h">'message'</span><span class="sy0">,</span>
    <span class="br0">&#91;</span><span class="st_h">'status'</span> <span class="sy0">=&amp;</span>gt<span class="sy0">;</span> <span class="kw4">false</span><span class="br0">&#93;</span><span class="sy0">,</span>
    <span class="br0">&#91;</span><span class="st_h">'status'</span> <span class="sy0">=&amp;</span>gt<span class="sy0">;</span> <span class="kw4">true</span><span class="sy0">,</span> <span class="st_h">'mtime'</span> <span class="sy0">=&amp;</span>gt<span class="sy0">;</span> <span class="kw3">date</span><span class="br0">&#40;</span><span class="st_h">'Y-m-d H:i:s'</span><span class="br0">&#41;</span><span class="br0">&#93;</span>
<span class="br0">&#41;</span><span class="sy0">-&amp;</span>gt<span class="sy0">;</span>renameColumn<span class="br0">&#40;</span>
    <span class="st_h">'message'</span><span class="sy0">,</span>
    <span class="st_h">'label'</span><span class="sy0">,</span>
    <span class="st_h">'content'</span>
<span class="br0">&#41;</span><span class="sy0">-&amp;</span>gt<span class="sy0">;</span>insert<span class="br0">&#40;</span>
    <span class="st_h">'message'</span><span class="sy0">,</span>
    <span class="br0">&#91;</span><span class="st_h">'label'</span> <span class="sy0">=&amp;</span>gt<span class="sy0">;</span> <span class="st_h">'test message'</span><span class="sy0">,</span> <span class="st_h">'status'</span> <span class="sy0">=&amp;</span>gt<span class="sy0">;</span> <span class="kw4">true</span><span class="sy0">,</span> <span class="st_h">'ctime'</span> <span class="sy0">=&amp;</span>gt<span class="sy0">;</span> <span class="kw3">date</span><span class="br0">&#40;</span><span class="st_h">'Y-m-d H:i:s'</span><span class="br0">&#41;</span><span class="sy0">,</span> <span class="st_h">'mtime'</span> <span class="sy0">=&amp;</span>gt<span class="sy0">;</span> <span class="kw3">date</span><span class="br0">&#40;</span><span class="st_h">'Y-m-d H:i:s'</span><span class="br0">&#41;</span><span class="sy0">,</span> <span class="st_h">'editor =&amp;gt; '</span>setup<span class="st_h">']
);</span></pre></div></div></div></div></div></div></div>






<p>This statements will delete the messages of type &#8220;custom&#8221;, drop the messages column afterwards, set the status to TRUE of all remaining records which updating the &#8220;mtime&#8221; column, rename the &#8220;label&#8221; column to &#8220;content&#8221; and insert a new test message into the table. All method calls can be concatenated because the Upscheme API offers a fluent interface and there&#8217;s also a <code>select()</code> method to query data:</p>





<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="php"><pre class="de1"><span class="re0">$this</span><span class="sy0">-&amp;</span>gt<span class="sy0">;</span>db<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">-&amp;</span>gt<span class="sy0">;</span>select<span class="br0">&#40;</span>
    <span class="st_h">'message'</span><span class="sy0">,</span>
    <span class="br0">&#91;</span><span class="st_h">'status'</span> <span class="sy0">=&amp;</span>gt<span class="sy0">;</span> <span class="kw4">false</span><span class="sy0">,</span> <span class="st_h">'type'</span> <span class="sy0">=&amp;</span>gt<span class="sy0">;</span> <span class="st_h">'old'</span><span class="br0">&#93;</span>
<span class="br0">&#41;</span><span class="sy0">;</span></pre></div></div></div></div></div></div></div>






<p>For more complex statement, Upscheme provides the <code>stmt()</code> method which gives you direct access to the Doctrine DBAL API:</p>





<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="php"><pre class="de1"><span class="re0">$result</span> <span class="sy0">=</span> <span class="re0">$this</span><span class="sy0">-&amp;</span>gt<span class="sy0">;</span>db<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">-&amp;</span>gt<span class="sy0">;</span>stmt<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">-&amp;</span>gt<span class="sy0">;</span>select<span class="br0">&#40;</span> <span class="st_h">'id'</span><span class="sy0">,</span> <span class="st_h">'content'</span> <span class="br0">&#41;</span>
    <span class="sy0">-&amp;</span>gt<span class="sy0">;</span>from<span class="br0">&#40;</span> <span class="st_h">'message'</span> <span class="br0">&#41;</span>
    <span class="sy0">-&amp;</span>gt<span class="sy0">;</span>where<span class="br0">&#40;</span> <span class="st_h">'status = 1'</span> <span class="br0">&#41;</span>
    <span class="sy0">-&amp;</span>gt<span class="sy0">;</span>execute<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
<span class="kw1">while</span><span class="br0">&#40;</span> <span class="re0">$row</span> <span class="sy0">=</span> <span class="re0">$result</span><span class="sy0">-&amp;</span>gt<span class="sy0">;</span>fetchAssociative<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#41;</span> <span class="br0">&#123;</span>
    <span class="re0">$map</span><span class="br0">&#91;</span><span class="re0">$row</span><span class="br0">&#91;</span><span class="st_h">'id'</span><span class="br0">&#93;</span><span class="br0">&#93;</span> <span class="sy0">=</span> <span class="re0">$row</span><span class="br0">&#91;</span><span class="st_h">'content'</span><span class="br0">&#93;</span><span class="sy0">;</span>
<span class="br0">&#125;</span></pre></div></div></div></div></div></div></div>






<h2>Summary</h2>



<p>Compared to Doctrine DBAL, Upscheme is very easy to use and also contains some workarounds for pitfalls in DBAL. Creating and updating the database schema is extremely simple and Upscheme saved up to 80% of the code in some setup tasks compared to the previous DBAL code in the Aimeos core.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://aimeos.org/tips/aimeos-2022-news/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>PHP: Array &gt; Map 2.0</title>
		<link>https://aimeos.org/tips/php-array-map-2-0/</link>
					<comments>https://aimeos.org/tips/php-array-map-2-0/#respond</comments>
		
		<dc:creator><![CDATA[aimeos]]></dc:creator>
		<pubDate>Wed, 10 Feb 2021 11:23:33 +0000</pubDate>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[array]]></category>
		<category><![CDATA[collection]]></category>
		<category><![CDATA[map]]></category>
		<guid isPermaLink="false">https://aimeos.org/tips/?p=751</guid>

					<description><![CDATA[The new 2.0 major release of the PHP map package is available which includes new methods and support for working with multi-dimensional arrays in an easy way. Additionally, it comes with the best documentation ever so you find everything you<span class="ellipsis">&#8230;</span><div class="read-more"><a href="https://aimeos.org/tips/php-array-map-2-0/">Read more <span class="screen-reader-text">PHP: Array > Map 2.0</span><span class="meta-nav"> &#8250;</span></a></div><!-- end of .read-more -->]]></description>
										<content:encoded><![CDATA[
<div class="wp-block-image"><figure class="aligncenter size-large"><a href="https://aimeos.org/tips/wp-content/uploads/2021/02/php-map-big.png"><img width="1024" height="542" src="https://aimeos.org/tips/wp-content/uploads/2021/02/php-map-big-1024x542.png" alt="" class="wp-image-752" srcset="https://aimeos.org/tips/wp-content/uploads/2021/02/php-map-big-1024x542.png 1024w, https://aimeos.org/tips/wp-content/uploads/2021/02/php-map-big-300x159.png 300w, https://aimeos.org/tips/wp-content/uploads/2021/02/php-map-big-768x406.png 768w, https://aimeos.org/tips/wp-content/uploads/2021/02/php-map-big-100x53.png 100w, https://aimeos.org/tips/wp-content/uploads/2021/02/php-map-big-150x79.png 150w, https://aimeos.org/tips/wp-content/uploads/2021/02/php-map-big-200x106.png 200w, https://aimeos.org/tips/wp-content/uploads/2021/02/php-map-big-450x238.png 450w, https://aimeos.org/tips/wp-content/uploads/2021/02/php-map-big-600x318.png 600w, https://aimeos.org/tips/wp-content/uploads/2021/02/php-map-big-900x476.png 900w, https://aimeos.org/tips/wp-content/uploads/2021/02/php-map-big.png 1200w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></figure></div>



<p>The new 2.0 major release of the PHP map package is available which includes new methods and support for working with multi-dimensional arrays in an easy way. Additionally, it comes with the best documentation ever so you find everything you need quickly!</p>



<p>Instead of applying independent PHP functions on arrays, use the PHP Map object to stream array data through several methods to transform, order and shorten its elements until the result exactly conforms to your requirements, for example:</p>





<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="php"><pre class="de1"><span class="re0">$data</span> <span class="sy0">=</span> <span class="br0">&#91;</span>
    <span class="br0">&#91;</span><span class="st_h">'name'</span> <span class="sy0">=&gt;</span> <span class="st_h">'Tom'</span><span class="sy0">,</span> <span class="st_h">'dep'</span> <span class="sy0">=&gt;</span> <span class="st_h">'Dev'</span><span class="sy0">,</span> <span class="st_h">'qty'</span> <span class="sy0">=&gt;</span> <span class="nu0">30</span><span class="br0">&#93;</span><span class="sy0">,</span>
    <span class="br0">&#91;</span><span class="st_h">'name'</span> <span class="sy0">=&gt;</span> <span class="st_h">'Bob'</span><span class="sy0">,</span> <span class="st_h">'dep'</span> <span class="sy0">=&gt;</span> <span class="st_h">'Sales'</span><span class="sy0">,</span> <span class="st_h">'qty'</span> <span class="sy0">=&gt;</span> <span class="nu0">50</span><span class="br0">&#93;</span><span class="sy0">,</span>
    <span class="br0">&#91;</span><span class="st_h">'name'</span> <span class="sy0">=&gt;</span> <span class="st_h">'Joe'</span><span class="sy0">,</span> <span class="st_h">'dep'</span> <span class="sy0">=&gt;</span> <span class="st_h">'Dev'</span><span class="sy0">,</span> <span class="st_h">'qty'</span> <span class="sy0">=&gt;</span> <span class="nu0">10</span><span class="br0">&#93;</span>
<span class="br0">&#93;</span><span class="sy0">;</span>
&nbsp;
<span class="co1">// get the person with the highest quantity in &quot;Dev&quot; department</span>
<span class="re0">$name</span> <span class="sy0">=</span> map<span class="br0">&#40;</span> <span class="re0">$data</span> <span class="br0">&#41;</span>
    <span class="sy0">-&gt;</span><span class="me1">groupBy</span><span class="br0">&#40;</span> <span class="st_h">'dep'</span> <span class="br0">&#41;</span><span class="sy0">-&gt;</span><span class="me1">only</span><span class="br0">&#40;</span> <span class="st_h">'Dev'</span> <span class="br0">&#41;</span>
    <span class="sy0">-&gt;</span><span class="me1">flat</span><span class="br0">&#40;</span> <span class="nu0">1</span> <span class="br0">&#41;</span><span class="sy0">-&gt;</span><span class="me1">col</span><span class="br0">&#40;</span> <span class="st_h">'name'</span><span class="sy0">,</span> <span class="st_h">'qty'</span> <span class="br0">&#41;</span>
    <span class="sy0">-&gt;</span><span class="kw3">ksort</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">-&gt;</span><span class="me1">last</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></div></div></div></div></div></div></div>






<p>To get the result in one statement is easier and much more elegant than the traditional way in PHP. The PHP Map object is perfectly suited to work on result sets returned by relational databases. You can transform them until you get a collection that exactly fits for your template generating the HTML for the frontend.</p>



<p>The PHP Map package combines the best from Laravel and CakePHP collections, jQuery, Backbone.js, and Lodash in an easy to use PHP package for every PHP application.</p>



<h2>What&#8217;s new in PHP Map 2.0</h2>



<p>One of the biggest new feature is the ability to pass a path of keys as parameter to several PHP Map methods to work on nested arrays directly. Instead of writing own code for diving into multi-dimensional arrays, you can now use the available methods to e.g. get a value by using:</p>





<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="php"><pre class="de1">map<span class="br0">&#40;</span> <span class="br0">&#91;</span><span class="st_h">'key'</span> <span class="sy0">=&gt;</span> <span class="br0">&#91;</span><span class="st_h">'to'</span> <span class="sy0">=&gt;</span> <span class="br0">&#91;</span><span class="st_h">'value'</span> <span class="sy0">=&gt;</span> <span class="st_h">'yes!'</span><span class="br0">&#93;</span><span class="br0">&#93;</span><span class="br0">&#93;</span> <span class="br0">&#41;</span>
    <span class="sy0">-&gt;</span><span class="me1">get</span><span class="br0">&#40;</span> <span class="st_h">'key/to/value'</span> <span class="br0">&#41;</span><span class="sy0">;</span> <span class="co1">// returns &quot;yes!&quot;</span></pre></div></div></div></div></div></div></div>






<p></p>



<p>This also works for more advanced methods like <code>col()</code> to reindex an array by using a nested key:</p>





<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="php"><pre class="de1"><span class="re0">$data</span> <span class="sy0">=</span> <span class="br0">&#91;</span>
    <span class="br0">&#91;</span><span class="st_h">'name'</span> <span class="sy0">=&gt;</span> <span class="st_h">'Tom'</span><span class="sy0">,</span> <span class="st_h">'addr'</span> <span class="sy0">=&gt;</span> <span class="br0">&#91;</span><span class="st_h">'zip'</span> <span class="sy0">=&gt;</span> <span class="st_h">'12AB'</span><span class="sy0">,</span> <span class="st_h">'city'</span> <span class="sy0">=&gt;</span> <span class="st_h">'NY'</span><span class="br0">&#93;</span><span class="br0">&#93;</span><span class="sy0">,</span>
    <span class="br0">&#91;</span><span class="st_h">'name'</span> <span class="sy0">=&gt;</span> <span class="st_h">'Bob'</span><span class="sy0">,</span> <span class="st_h">'addr'</span> <span class="sy0">=&gt;</span> <span class="br0">&#91;</span><span class="st_h">'zip'</span> <span class="sy0">=&gt;</span> <span class="st_h">'23WD'</span><span class="sy0">,</span> <span class="st_h">'city'</span> <span class="sy0">=&gt;</span> <span class="st_h">'LA'</span><span class="br0">&#93;</span><span class="br0">&#93;</span>
<span class="br0">&#93;</span><span class="sy0">;</span>
&nbsp;
<span class="re0">$map</span> <span class="sy0">=</span> map<span class="br0">&#40;</span> <span class="re0">$data</span> <span class="br0">&#41;</span><span class="sy0">-&gt;</span><span class="me1">col</span><span class="br0">&#40;</span> <span class="st_h">'name'</span><span class="sy0">,</span> <span class="st_h">'addr/zip'</span> <span class="br0">&#41;</span><span class="sy0">;</span>
<span class="co1">// ['12AB' =&gt; 'Tom', '23WD' =&gt; 'Bob']</span></pre></div></div></div></div></div></div></div>






<p>By default, a dot (&#8220;/&#8221;) is used as seperator between the array key names but you can change that for the current map using the <code>sep()</code> method:</p>





<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="php"><pre class="de1"><span class="re0">$map</span> <span class="sy0">=</span> map<span class="br0">&#40;</span> <span class="re0">$data</span> <span class="br0">&#41;</span><span class="sy0">-&gt;</span><span class="me1">sep</span><span class="br0">&#40;</span> <span class="st_h">'.'</span> <span class="br0">&#41;</span><span class="sy0">-&gt;</span><span class="me1">col</span><span class="br0">&#40;</span> <span class="st_h">'name'</span><span class="sy0">,</span> <span class="st_h">'addr.zip'</span> <span class="br0">&#41;</span><span class="sy0">;</span></pre></div></div></div></div></div></div></div>






<p>If you want to use another seperator in all new PHP Map objects (existing ones will keep their separator), you can change the delimiter globally with the <code>delimiter()</code> method:</p>





<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="php"><pre class="de1">Map<span class="sy0">::</span><span class="me2">delimiter</span><span class="br0">&#40;</span> <span class="st_h">','</span> <span class="br0">&#41;</span><span class="sy0">;</span></pre></div></div></div></div></div></div></div>






<p>It also returns the delimiter used before if you want to revert the used delimiter later in your code.</p>



<h2>Breaking changes in PHP Map 2.0</h2>



<p>The new major version contains a few breaking changes to avoid potential problems that came up in the past. You won&#8217;t be affected by most of them but you should have a look to prevent unexpected behaviour.</p>



<h3>New slash separator</h3>



<p>The most important change affects parameter values including slashes because they are now treated as path separators for nested arrays.</p>





<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="php"><pre class="de1"><span class="re0">$data</span> <span class="sy0">=</span> <span class="br0">&#91;</span>
    <span class="st_h">'item/id'</span> <span class="sy0">=&gt;</span> <span class="nu0">1</span><span class="sy0">,</span>
    <span class="st_h">'item/code'</span> <span class="sy0">=&gt;</span> <span class="st_h">'test'</span><span class="sy0">,</span>
    <span class="st_h">'item/name'</span> <span class="sy0">=&gt;</span> <span class="st_h">'Test'</span>
<span class="br0">&#93;</span><span class="sy0">;</span>
&nbsp;
map<span class="br0">&#40;</span> <span class="re0">$data</span> <span class="br0">&#41;</span><span class="sy0">-&gt;</span><span class="me1">col</span><span class="br0">&#40;</span> <span class="st_h">'item/code'</span><span class="sy0">,</span> <span class="st_h">'item/id'</span> <span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
<span class="co1">// 1.x</span>
<span class="br0">&#91;</span><span class="nu0">1</span> <span class="sy0">=&gt;</span> <span class="st_h">'test'</span><span class="br0">&#93;</span>
&nbsp;
<span class="co1">// 2.x</span>
<span class="br0">&#91;</span><span class="br0">&#93;</span>
<span class="co1">// use instead</span>
map<span class="br0">&#40;</span> <span class="re0">$data</span> <span class="br0">&#41;</span><span class="sy0">-&gt;</span><span class="me1">sep</span><span class="br0">&#40;</span> <span class="st_h">'.'</span> <span class="br0">&#41;</span><span class="sy0">-&gt;</span><span class="me1">col</span><span class="br0">&#40;</span> <span class="st_h">'item/code'</span><span class="sy0">,</span> <span class="st_h">'item/id'</span> <span class="br0">&#41;</span><span class="sy0">;</span></pre></div></div></div></div></div></div></div>






<h3>jQuery style method calls</h3>



<p>You can call methods of objects in a map like this:</p>





<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="php"><pre class="de1"><span class="co1">// MyClass implements setStatus() (returning $this) and</span>
<span class="co1">// getCode() (initialized by constructor)</span>
&nbsp;
<span class="re0">$map</span> <span class="sy0">=</span> Map<span class="sy0">::</span><span class="me2">from</span><span class="br0">&#40;</span> <span class="br0">&#91;</span>
    <span class="st_h">'a'</span> <span class="sy0">=&gt;</span> <span class="kw2">new</span> MyClass<span class="br0">&#40;</span> <span class="st_h">'x'</span> <span class="br0">&#41;</span><span class="sy0">,</span>
    <span class="st_h">'b'</span> <span class="sy0">=&gt;</span> <span class="kw2">new</span> MyClass<span class="br0">&#40;</span> <span class="st_h">'y'</span> <span class="br0">&#41;</span>
<span class="br0">&#93;</span> <span class="br0">&#41;</span><span class="sy0">;</span>
<span class="re0">$map</span><span class="sy0">-&gt;</span><span class="me1">setStatus</span><span class="br0">&#40;</span> <span class="nu0">1</span> <span class="br0">&#41;</span><span class="sy0">-&gt;</span><span class="me1">getCode</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">-&gt;</span><span class="me1">toArray</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></div></div></div></div></div></div></div>






<p>Before, the objects had been checked if they really implement the <code>setStatus()</code> and <code>getCode()</code> methods.</p>



<p>To avoid returning an empty map if the method name is wrong or the called method is catched by the <code>__call()</code> magic method, this isn’t the case any more. If the method isn’t implemented by all objects, PHP generates a fatal error now for better error tracing.</p>



<h3>Second equals() parameter</h3>



<p>The <code>$assoc</code> parameter of the&nbsp;<a href="https://php-map.org/#equals"><code>equals()</code></a>&nbsp;method to compare keys too has been removed and now, you must use the&nbsp;<a href="https://php-map.org/#is"><code>is()</code></a>&nbsp;method instead:</p>





<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="php"><pre class="de1"><span class="co1">// 1.x</span>
map<span class="br0">&#40;</span> <span class="br0">&#91;</span><span class="st_h">'one'</span> <span class="sy0">=&gt;</span> <span class="nu0">1</span><span class="br0">&#93;</span> <span class="br0">&#41;</span><span class="sy0">-&gt;</span><span class="me1">equals</span><span class="br0">&#40;</span> <span class="br0">&#91;</span><span class="st_h">'one'</span> <span class="sy0">=&gt;</span> <span class="nu0">1</span><span class="br0">&#93;</span><span class="sy0">,</span> <span class="kw4">true</span> <span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
<span class="co1">// 2.x</span>
map<span class="br0">&#40;</span> <span class="br0">&#91;</span><span class="st_h">'one'</span> <span class="sy0">=&gt;</span> <span class="nu0">1</span><span class="br0">&#93;</span> <span class="br0">&#41;</span><span class="sy0">-&gt;</span><span class="me1">is</span><span class="br0">&#40;</span> <span class="br0">&#91;</span><span class="st_h">'one'</span> <span class="sy0">=&gt;</span> <span class="nu0">1</span><span class="br0">&#93;</span> <span class="br0">&#41;</span><span class="sy0">;</span></pre></div></div></div></div></div></div></div>






<h3>New find() argument</h3>



<p>The&nbsp;<a href="https://php-map.org/#find"><code>find()</code></a>&nbsp;method now accepts a default value or exception object as second argument and the&nbsp;<code>$reverse</code>&nbsp;argument is at the third position now:</p>





<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="php"><pre class="de1"><span class="co1">// 1.x</span>
Map<span class="sy0">::</span><span class="me2">from</span><span class="br0">&#40;</span> <span class="br0">&#91;</span><span class="st_h">'a'</span><span class="sy0">,</span> <span class="st_h">'c'</span><span class="sy0">,</span> <span class="st_h">'e'</span><span class="br0">&#93;</span> <span class="br0">&#41;</span><span class="sy0">-&gt;</span><span class="me1">find</span><span class="br0">&#40;</span> <span class="kw2">function</span><span class="br0">&#40;</span> <span class="re0">$value</span><span class="sy0">,</span> <span class="re0">$key</span> <span class="br0">&#41;</span> <span class="br0">&#123;</span>
    <span class="kw1">return</span> <span class="re0">$value</span> <span class="sy0">&gt;=</span> <span class="st_h">'b'</span><span class="sy0">;</span>
<span class="br0">&#125;</span><span class="sy0">,</span> <span class="kw4">true</span> <span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
<span class="co1">// 2.x</span>
Map<span class="sy0">::</span><span class="me2">from</span><span class="br0">&#40;</span> <span class="br0">&#91;</span><span class="st_h">'a'</span><span class="sy0">,</span> <span class="st_h">'c'</span><span class="sy0">,</span> <span class="st_h">'e'</span><span class="br0">&#93;</span> <span class="br0">&#41;</span><span class="sy0">-&gt;</span><span class="me1">find</span><span class="br0">&#40;</span> <span class="kw2">function</span><span class="br0">&#40;</span> <span class="re0">$value</span><span class="sy0">,</span> <span class="re0">$key</span> <span class="br0">&#41;</span> <span class="br0">&#123;</span>
    <span class="kw1">return</span> <span class="re0">$value</span> <span class="sy0">&gt;=</span> <span class="st_h">'b'</span><span class="sy0">;</span>
<span class="br0">&#125;</span><span class="sy0">,</span> <span class="kw4">null</span><span class="sy0">,</span> <span class="kw4">true</span> <span class="br0">&#41;</span><span class="sy0">;</span></pre></div></div></div></div></div></div></div>






<h3>Semantic change in groupBy()</h3>



<p>Before, items have been grouped by the key string itself if the key passed to&nbsp;<a href="https://php-map.org/#groupby"><code>groupBy()</code></a>&nbsp;didn’t exist. To offer easier checking and sorting of the keys, an empty string is used as key now:</p>





<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="php"><pre class="de1">Map<span class="sy0">::</span><span class="me2">from</span><span class="br0">&#40;</span> <span class="br0">&#91;</span>
    <span class="nu0">10</span> <span class="sy0">=&gt;</span> <span class="br0">&#91;</span><span class="st_h">'aid'</span> <span class="sy0">=&gt;</span> <span class="nu0">123</span><span class="sy0">,</span> <span class="st_h">'code'</span> <span class="sy0">=&gt;</span> <span class="st_h">'x-abc'</span><span class="br0">&#93;</span><span class="sy0">,</span>
<span class="br0">&#93;</span> <span class="br0">&#41;</span><span class="sy0">-&gt;</span><span class="me1">groupBy</span><span class="br0">&#40;</span> <span class="st_h">'xid'</span> <span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
<span class="co1">// 1.x</span>
<span class="br0">&#91;</span>
    <span class="st_h">'xid'</span> <span class="sy0">=&gt;</span> <span class="br0">&#91;</span>
        <span class="nu0">10</span> <span class="sy0">=&gt;</span> <span class="br0">&#91;</span><span class="st_h">'aid'</span> <span class="sy0">=&gt;</span> <span class="nu0">123</span><span class="sy0">,</span> <span class="st_h">'code'</span> <span class="sy0">=&gt;</span> <span class="st_h">'x-abc'</span><span class="br0">&#93;</span>
    <span class="br0">&#93;</span>
<span class="br0">&#93;</span>
&nbsp;
<span class="co1">// 2.x</span>
<span class="br0">&#91;</span>
    <span class="st_h">''</span> <span class="sy0">=&gt;</span> <span class="br0">&#91;</span>
        <span class="nu0">10</span> <span class="sy0">=&gt;</span> <span class="br0">&#91;</span><span class="st_h">'aid'</span> <span class="sy0">=&gt;</span> <span class="nu0">123</span><span class="sy0">,</span> <span class="st_h">'code'</span> <span class="sy0">=&gt;</span> <span class="st_h">'x-abc'</span><span class="br0">&#93;</span>
    <span class="br0">&#93;</span>
<span class="br0">&#93;</span></pre></div></div></div></div></div></div></div>






<h3>Semantic change in offsetExists()</h3>



<p>The&nbsp;<a href="https://php-map.org/#offsetexists"><code>offsetExists()</code></a>&nbsp;method uses&nbsp;<code>isset()</code>&nbsp;instead of <code>array_key_exists()</code> now to be in line with typical PHP behavior. Thus, keys with NULL values are now treated differently:</p>





<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="php"><pre class="de1"><span class="re0">$m</span> <span class="sy0">=</span> Map<span class="sy0">::</span><span class="me2">from</span><span class="br0">&#40;</span> <span class="br0">&#91;</span><span class="st_h">'foo'</span> <span class="sy0">=&gt;</span> <span class="kw4">null</span><span class="br0">&#93;</span> <span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
<span class="co1">// 1.x</span>
<span class="kw3">isset</span><span class="br0">&#40;</span> <span class="re0">$m</span><span class="br0">&#91;</span><span class="st_h">'foo'</span><span class="br0">&#93;</span> <span class="br0">&#41;</span><span class="sy0">;</span> <span class="co1">// true</span>
&nbsp;
<span class="co1">// 2.x</span>
<span class="kw3">isset</span><span class="br0">&#40;</span> <span class="re0">$m</span><span class="br0">&#91;</span><span class="st_h">'foo'</span><span class="br0">&#93;</span> <span class="br0">&#41;</span><span class="sy0">;</span> <span class="co1">// false</span></pre></div></div></div></div></div></div></div>






<h3>Renamed split() to explode()</h3>



<p>To avoid conflicts with the Laravel <code>split()</code> method and to be in line with the PHP&nbsp;<code>explode()</code>&nbsp;method, the static&nbsp;<code>Map::split()</code>&nbsp;method has been renamed to&nbsp;<code><a href="https://php-map.org/#explode">Map::explode()</a></code>.&nbsp;Also, the argument order has changed:</p>





<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="php"><pre class="de1"><span class="co1">// 1.x</span>
Map<span class="sy0">::</span><span class="kw3">split</span><span class="br0">&#40;</span> <span class="st_h">'a,b,c'</span><span class="sy0">,</span> <span class="st_h">','</span> <span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
<span class="co1">// 2.x</span>
Map<span class="sy0">::</span><span class="kw3">explode</span><span class="br0">&#40;</span> <span class="st_h">','</span><span class="sy0">,</span> <span class="st_h">'a,b,c'</span> <span class="br0">&#41;</span><span class="sy0">;</span></pre></div></div></div></div></div></div></div>



]]></content:encoded>
					
					<wfw:commentRss>https://aimeos.org/tips/php-array-map-2-0/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>PHP: Advanced map methods</title>
		<link>https://aimeos.org/tips/php-advanced-map-methods/</link>
					<comments>https://aimeos.org/tips/php-advanced-map-methods/#comments</comments>
		
		<dc:creator><![CDATA[aimeos]]></dc:creator>
		<pubDate>Wed, 11 Mar 2020 10:42:13 +0000</pubDate>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[array]]></category>
		<category><![CDATA[map]]></category>
		<guid isPermaLink="false">https://aimeos.org/tips/?p=533</guid>

					<description><![CDATA[The&#160;PHP Map package&#160;contains many methods to ease your day to day work. They are&#160;extremely helpful&#160;in a lot of situations where you’ve written custom code up to now.&#160;This tutorial explains some of the&#160;most useful ones&#160;you don&#8217;t want to miss any more!<span class="ellipsis">&#8230;</span><div class="read-more"><a href="https://aimeos.org/tips/php-advanced-map-methods/">Read more <span class="screen-reader-text">PHP: Advanced map methods</span><span class="meta-nav"> &#8250;</span></a></div><!-- end of .read-more -->]]></description>
										<content:encoded><![CDATA[
<div class="wp-block-image"><figure class="aligncenter size-large"><img width="1024" height="538" src="https://aimeos.org/tips/wp-content/uploads/2020/03/php-map-advanced-1-1024x538.png" alt="" class="wp-image-575" srcset="https://aimeos.org/tips/wp-content/uploads/2020/03/php-map-advanced-1-1024x538.png 1024w, https://aimeos.org/tips/wp-content/uploads/2020/03/php-map-advanced-1-300x158.png 300w, https://aimeos.org/tips/wp-content/uploads/2020/03/php-map-advanced-1-768x403.png 768w, https://aimeos.org/tips/wp-content/uploads/2020/03/php-map-advanced-1-100x53.png 100w, https://aimeos.org/tips/wp-content/uploads/2020/03/php-map-advanced-1-150x79.png 150w, https://aimeos.org/tips/wp-content/uploads/2020/03/php-map-advanced-1-200x105.png 200w, https://aimeos.org/tips/wp-content/uploads/2020/03/php-map-advanced-1-450x236.png 450w, https://aimeos.org/tips/wp-content/uploads/2020/03/php-map-advanced-1-600x315.png 600w, https://aimeos.org/tips/wp-content/uploads/2020/03/php-map-advanced-1-900x473.png 900w, https://aimeos.org/tips/wp-content/uploads/2020/03/php-map-advanced-1.png 1200w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure></div>



<p>The&nbsp;<a href="https://github.com/aimeos/map">PHP Map package</a>&nbsp;contains many methods to ease your day to day work. They are&nbsp;<strong>extremely helpful</strong>&nbsp;in a lot of situations where you’ve written custom code up to now.&nbsp;This tutorial explains some of the&nbsp;<strong>most useful ones</strong>&nbsp;you don&#8217;t want to miss any more!</p>



<ul><li><a href="https://github.com/aimeos/map">Documentation at Github</a></li><li><a href="https://packagist.org/packages/aimeos/map">Composer package at Packagist</a></li></ul>



<span id="more-533"></span>



<h2>Installation</h2>



<p>To use the PHP Map package, you have to add it to your composer based application:</p>



<p><code>composer req aimeos/map</code></p>



<p>Afterwards, there will be a map() function available, that creates a Map object which offers the methods explained.</p>



<h2>col(): Map key/value pairs</h2>



<p>There are numerous times when you need to transform an existing array into a list of key/value pairs. Think about a list of database records for example which should be indexed by ID instead of a sequential index. The <code>col()</code> method creates that without the necessity of a loop:</p>





<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="php"><pre class="de1"><span class="re0">$rows</span> <span class="sy0">=</span> <span class="br0">&#91;</span><span class="br0">&#91;</span><span class="st_h">'id'</span> <span class="sy0">=&gt;</span> <span class="nu0">1</span><span class="sy0">,</span> <span class="st_h">'code'</span> <span class="sy0">=&gt;</span> <span class="st_h">'a'</span><span class="br0">&#93;</span><span class="sy0">,</span> <span class="br0">&#91;</span><span class="st_h">'id'</span> <span class="sy0">=&gt;</span> <span class="nu0">3</span><span class="sy0">,</span> <span class="st_h">'code'</span> <span class="sy0">=&gt;</span> <span class="st_h">'d'</span><span class="br0">&#93;</span><span class="br0">&#93;</span><span class="sy0">;</span>
<span class="re0">$result</span> <span class="sy0">=</span> map<span class="br0">&#40;</span> <span class="re0">$rows</span> <span class="br0">&#41;</span><span class="sy0">-&gt;</span><span class="me1">col</span><span class="br0">&#40;</span> <span class="st_h">'code'</span><span class="sy0">,</span> <span class="st_h">'id'</span> <span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
<span class="co1">// Result equals:</span>
map<span class="br0">&#40;</span> <span class="br0">&#91;</span><span class="nu0">1</span> <span class="sy0">=&gt;</span> <span class="st_h">'a'</span><span class="sy0">,</span> <span class="nu0">3</span> <span class="sy0">=&gt;</span> <span class="st_h">'d'</span><span class="br0">&#93;</span> <span class="br0">&#41;</span><span class="sy0">;</span></pre></div></div></div></div></div></div></div>






<p>This does also work with objects if they implement the magic PHP <code>__get()</code> method.</p>



<h2>collapse() and flat(): Transform multi-dimensional arrays</h2>



<p>Do you remember the last time when you had a multi-dimensional array and you needed a flat array of all elements? If you know the maximum depth, you can nest several loops but if not, you need to write a recursive function, which is very cumbersome. The Map object offers the <code>flat()</code> method, that can to do that in one line:</p>





<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="php"><pre class="de1"><span class="re0">$array</span> <span class="sy0">=</span> <span class="br0">&#91;</span><span class="br0">&#91;</span><span class="nu0">1</span><span class="sy0">,</span> <span class="nu0">2</span><span class="br0">&#93;</span><span class="sy0">,</span> <span class="br0">&#91;</span><span class="nu0">3</span><span class="sy0">,</span> <span class="br0">&#91;</span><span class="nu0">4</span><span class="sy0">,</span> <span class="nu0">5</span><span class="br0">&#93;</span><span class="br0">&#93;</span><span class="br0">&#93;</span><span class="sy0">;</span>
<span class="re0">$result</span> <span class="sy0">=</span> map<span class="br0">&#40;</span> <span class="re0">$array</span> <span class="br0">&#41;</span><span class="sy0">-&gt;</span><span class="me1">flat</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
<span class="co1">// Result equals:</span>
map<span class="br0">&#40;</span> <span class="br0">&#91;</span><span class="nu0">1</span><span class="sy0">,</span> <span class="nu0">2</span><span class="sy0">,</span> <span class="nu0">3</span><span class="sy0">,</span> <span class="nu0">4</span><span class="sy0">,</span> <span class="nu0">5</span><span class="br0">&#93;</span> <span class="br0">&#41;</span><span class="sy0">;</span></pre></div></div></div></div></div></div></div>






<p>There&#8217;s a similar method named collapse(), that does almost the same but keeps the key of each value. Thus, it will overwrite elements with duplicate keys (also numeric keys):</p>





<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="php"><pre class="de1"><span class="re0">$array</span> <span class="sy0">=</span> <span class="br0">&#91;</span><span class="br0">&#91;</span><span class="st_h">'a'</span> <span class="sy0">=&gt;</span> <span class="nu0">1</span><span class="sy0">,</span> <span class="st_h">'b'</span> <span class="sy0">=&gt;</span> <span class="nu0">2</span><span class="br0">&#93;</span><span class="sy0">,</span> <span class="br0">&#91;</span><span class="st_h">'c'</span> <span class="sy0">=&gt;</span> <span class="nu0">3</span><span class="sy0">,</span> <span class="br0">&#91;</span><span class="st_h">'a'</span> <span class="sy0">=&gt;</span> <span class="nu0">4</span><span class="sy0">,</span> <span class="st_h">'b'</span> <span class="sy0">=&gt;</span> <span class="nu0">5</span><span class="br0">&#93;</span><span class="br0">&#93;</span><span class="br0">&#93;</span><span class="sy0">;</span>
<span class="re0">$result</span> <span class="sy0">=</span> map<span class="br0">&#40;</span> <span class="re0">$array</span> <span class="br0">&#41;</span><span class="sy0">-&gt;</span><span class="me1">collapse</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
<span class="co1">// Result equals:</span>
map<span class="br0">&#40;</span> <span class="br0">&#91;</span><span class="st_h">'a'</span> <span class="sy0">=&gt;</span> <span class="nu0">4</span><span class="sy0">,</span> <span class="st_h">'b'</span> <span class="sy0">=&gt;</span> <span class="nu0">5</span><span class="sy0">,</span> <span class="st_h">'c'</span> <span class="sy0">=&gt;</span> <span class="nu0">3</span><span class="br0">&#93;</span> <span class="br0">&#41;</span><span class="sy0">;</span></pre></div></div></div></div></div></div></div>






<p>Both methods accept the number of levels they should collapse or flatten as parameter. That way it&#8217;s easy to keep e.g. the third level and above unflattened or uncollapsed.</p>



<h2>concat(), merge() and union(): Differences in combining arrays</h2>



<p>In PHP, you can combine arrays using <code>array_merge()</code> or the <code>+</code> operator but their results are different. The PHP map package also offers the <code>concat()</code> method:</p>





<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="php"><pre class="de1"><span class="re0">$one</span> <span class="sy0">=</span> <span class="br0">&#91;</span><span class="nu0">0</span> <span class="sy0">=&gt;</span> <span class="st_h">'a'</span><span class="sy0">,</span> <span class="st_h">'b'</span> <span class="sy0">=&gt;</span> <span class="nu0">2</span><span class="br0">&#93;</span><span class="sy0">;</span>
<span class="re0">$two</span> <span class="sy0">=</span> <span class="br0">&#91;</span><span class="st_h">'b'</span> <span class="sy0">=&gt;</span> <span class="nu0">3</span><span class="sy0">,</span> <span class="nu0">0</span> <span class="sy0">=&gt;</span> <span class="nu0">4</span><span class="br0">&#93;</span><span class="sy0">;</span>
&nbsp;
<span class="re0">$result</span> <span class="sy0">=</span> map<span class="br0">&#40;</span> <span class="re0">$one</span> <span class="br0">&#41;</span><span class="sy0">-&gt;</span><span class="me1">concat</span><span class="br0">&#40;</span> <span class="re0">$two</span> <span class="br0">&#41;</span><span class="sy0">;</span>
<span class="co1">//equals map( [0 =&gt; 'a', 'b' =&gt; 2, 1 =&gt; 3, 2 =&gt; 4] );</span>
&nbsp;
<span class="re0">$result</span> <span class="sy0">=</span> map<span class="br0">&#40;</span> <span class="re0">$one</span> <span class="br0">&#41;</span><span class="sy0">-&gt;</span><span class="me1">merge</span><span class="br0">&#40;</span> <span class="re0">$two</span> <span class="br0">&#41;</span><span class="sy0">;</span>
<span class="co1">//equals map( [0 =&gt; 'a', 'b' =&gt; 3, 1 =&gt; 4] );</span>
&nbsp;
<span class="re0">$result</span> <span class="sy0">=</span> map<span class="br0">&#40;</span> <span class="re0">$one</span> <span class="br0">&#41;</span><span class="sy0">-&gt;</span><span class="me1">union</span><span class="br0">&#40;</span> <span class="re0">$two</span> <span class="br0">&#41;</span><span class="sy0">;</span>
<span class="co1">//equals map( [0 =&gt; 'a', 'b' =&gt; 2] );</span></pre></div></div></div></div></div></div></div>






<p><code>concat()</code> combines the elements of both arrays but doesn&#8217;t care about their keys and the resulting list will contain all elements of both arrays. <code>merge()</code> which uses the <code>array_merge()</code> function overwrites existing string keys but renumbers numeric keys. <code>union()</code> is the same as using the <code>+</code> operator and doesn&#8217;t add elements whose keys does already exist.</p>



<h2>equals(): Test if arrays contains the same elements</h2>



<p>To compare arrays, PHP only offers the <code>==</code> and <code>===</code> operators. They return only true if both array contains the same elements with the same keys (and the same order in case of <code>===</code>). Contrary, the equals() method of the Map object can also test arrays without checking the keys:</p>





<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="php"><pre class="de1"><span class="re0">$one</span> <span class="sy0">=</span> <span class="br0">&#91;</span><span class="st_h">'a'</span><span class="sy0">,</span> <span class="st_h">'b'</span><span class="br0">&#93;</span><span class="sy0">;</span>
<span class="re0">$two</span> <span class="sy0">=</span> <span class="br0">&#91;</span><span class="st_h">'b'</span><span class="sy0">,</span> <span class="st_h">'a'</span><span class="br0">&#93;</span><span class="sy0">;</span>
&nbsp;
map<span class="br0">&#40;</span> <span class="re0">$one</span> <span class="br0">&#41;</span><span class="sy0">-&gt;</span><span class="me1">equals</span><span class="br0">&#40;</span> <span class="re0">$two</span> <span class="br0">&#41;</span><span class="sy0">;</span> <span class="co1">// true</span>
map<span class="br0">&#40;</span> <span class="re0">$one</span> <span class="br0">&#41;</span><span class="sy0">-&gt;</span><span class="me1">equals</span><span class="br0">&#40;</span> <span class="re0">$two</span><span class="sy0">,</span> <span class="kw4">true</span> <span class="br0">&#41;</span><span class="sy0">;</span> <span class="co1">// false</span></pre></div></div></div></div></div></div></div>






<p>When passing <code>true</code> as second parameter, <code>equals()</code> works like the <code>==</code> operator.</p>



<h2>find(): Return the first matching element</h2>



<p>Sometimes, you need the first element from an array that matches your needs. The Map object offers the find() method which allows you to pass a closure function as parameter. This anonymous function can check whose element matches your needs:</p>





<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="php"><pre class="de1">map<span class="br0">&#40;</span> <span class="br0">&#91;</span><span class="st_h">'a'</span><span class="sy0">,</span> <span class="st_h">'c'</span><span class="sy0">,</span> <span class="st_h">'e'</span><span class="br0">&#93;</span> <span class="br0">&#41;</span><span class="sy0">-&gt;</span><span class="me1">find</span><span class="br0">&#40;</span> <span class="kw2">function</span><span class="br0">&#40;</span> <span class="re0">$value</span><span class="sy0">,</span> <span class="re0">$key</span> <span class="br0">&#41;</span> <span class="br0">&#123;</span>
    <span class="kw1">return</span> <span class="re0">$value</span> <span class="sy0">&gt;=</span> <span class="st_h">'b'</span><span class="sy0">;</span>
<span class="br0">&#125;</span> <span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
<span class="co1">// Result equals 'c'</span></pre></div></div></div></div></div></div></div>






<p>If no matching value is found, <code>null</code> is returned. If you pass <code>true</code> as second parameter, the search for the matching element will be reversed and you will get the last matching element.</p>



<h2>first(), last(), get() and pull(): Advanced ways to retrieve an element</h2>



<p>Fetching the first, last or any element of a list of elements is very handy and most useful in many cases. But the PHP Map object offers more than that. What if those methods don&#8217;t return null if no element is found but throw an exception or execute a closure? Instead of:</p>





<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="php"><pre class="de1"><span class="kw1">if</span><span class="br0">&#40;</span> <span class="br0">&#40;</span> <span class="re0">$item</span> <span class="sy0">=</span> map<span class="br0">&#40;</span> <span class="br0">&#91;</span><span class="br0">&#93;</span> <span class="br0">&#41;</span> <span class="br0">&#41;</span><span class="sy0">-&gt;</span><span class="me1">first</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="sy0">===</span> <span class="kw4">null</span> <span class="br0">&#41;</span> <span class="br0">&#123;</span>
    <span class="kw1">throw</span> <span class="kw2">new</span> \Exception<span class="br0">&#40;</span> <span class="st_h">'error'</span> <span class="br0">&#41;</span><span class="sy0">;</span>
<span class="br0">&#125;</span>
&nbsp;
<span class="kw1">if</span><span class="br0">&#40;</span> <span class="br0">&#40;</span> <span class="re0">$item</span> <span class="sy0">=</span> map<span class="br0">&#40;</span> <span class="br0">&#91;</span><span class="br0">&#93;</span> <span class="br0">&#41;</span> <span class="br0">&#41;</span><span class="sy0">-&gt;</span><span class="me1">last</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="sy0">===</span> <span class="kw4">null</span> <span class="br0">&#41;</span> <span class="br0">&#123;</span>
    <span class="co1">// fetch and return record from database</span>
<span class="br0">&#125;</span>
<span class="re0">$id</span> <span class="sy0">=</span> <span class="re0">$item</span><span class="sy0">-&gt;</span><span class="me1">getId</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></div></div></div></div></div></div></div>






<p>you can simply write:</p>





<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="php"><pre class="de1"><span class="re0">$id</span> <span class="sy0">=</span> map<span class="br0">&#40;</span> <span class="br0">&#91;</span><span class="br0">&#93;</span> <span class="br0">&#41;</span><span class="sy0">-&gt;</span><span class="me1">first</span><span class="br0">&#40;</span> <span class="kw2">new</span> \Exception<span class="br0">&#40;</span> <span class="st_h">'error'</span> <span class="br0">&#41;</span> <span class="br0">&#41;</span><span class="sy0">-&gt;</span><span class="me1">getId</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
<span class="re0">$id</span> <span class="sy0">=</span> map<span class="br0">&#40;</span> <span class="br0">&#91;</span><span class="br0">&#93;</span> <span class="br0">&#41;</span><span class="sy0">-&gt;</span><span class="me1">last</span><span class="br0">&#40;</span> <span class="kw2">function</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
    <span class="co1">// fetch and return record from database</span>
<span class="br0">&#125;</span> <span class="br0">&#41;</span><span class="sy0">-&gt;</span><span class="me1">getId</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></div></div></div></div></div></div></div>






<p>All methods (<code>first()</code>, <code>last()</code>, <code>get()</code> and <code>pull()</code>) methods accept either an exception that&#8217;s thrown or a closure that&#8217;s executed if no element is available. Thus, it saves you the annoying checks that  make you code full of if/else statements.</p>



<p>If you pass an exception, the exception object is created whether it&#8217;s used or not. This is no problem as long as you don&#8217;t do that in a loop. Then, create one exception object before the loop and pass only the variable to the methods.</p>



<h2>in(): Check if several elements are in the list</h2>



<p>To test if an value is in a list of elements with <code>in()</code> isn&#8217;t much different than using <code>in_array()</code>. But what if you need to do that several times with different elements? Then, <code>in()</code> takes away the burden of doing that within a loop:</p>





<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="php"><pre class="de1">map<span class="br0">&#40;</span> <span class="br0">&#91;</span><span class="st_h">'a'</span><span class="sy0">,</span> <span class="st_h">'b'</span><span class="sy0">,</span> <span class="st_h">'c'</span><span class="br0">&#93;</span> <span class="br0">&#41;</span><span class="sy0">-&gt;</span><span class="me1">in</span><span class="br0">&#40;</span> <span class="st_h">'b'</span> <span class="br0">&#41;</span><span class="sy0">;</span> <span class="co1">// true</span>
map<span class="br0">&#40;</span> <span class="br0">&#91;</span><span class="st_h">'a'</span><span class="sy0">,</span> <span class="st_h">'b'</span><span class="sy0">,</span> <span class="st_h">'c'</span><span class="br0">&#93;</span> <span class="br0">&#41;</span><span class="sy0">-&gt;</span><span class="me1">in</span><span class="br0">&#40;</span> <span class="br0">&#91;</span><span class="st_h">'b'</span><span class="sy0">,</span> <span class="st_h">'a'</span><span class="br0">&#93;</span> <span class="br0">&#41;</span><span class="sy0">;</span> <span class="co1">// true</span>
map<span class="br0">&#40;</span> <span class="br0">&#91;</span><span class="st_h">'a'</span><span class="sy0">,</span> <span class="st_h">'b'</span><span class="sy0">,</span> <span class="st_h">'c'</span><span class="br0">&#93;</span> <span class="br0">&#41;</span><span class="sy0">-&gt;</span><span class="me1">in</span><span class="br0">&#40;</span> <span class="br0">&#91;</span><span class="st_h">'d'</span><span class="sy0">,</span> <span class="st_h">'a'</span><span class="br0">&#93;</span> <span class="br0">&#41;</span><span class="sy0">;</span> <span class="co1">// false</span></pre></div></div></div></div></div></div></div>






<p>The <code>in()</code> method of the Map object checks if all elements of the passed array are available in the list and only then it returns true.</p>



<h2>toJson(): Encode everything into JSON</h2>



<p>When working with APIs, you almost always need to encode the result into its JSON representation. The PHP map object offers a convenient way to transform all elements to JSON:</p>





<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="php"><pre class="de1">map<span class="br0">&#40;</span> <span class="br0">&#91;</span><span class="st_h">'a'</span><span class="sy0">,</span> <span class="st_h">'b'</span><span class="sy0">,</span> <span class="br0">&#91;</span><span class="st_h">'c'</span><span class="sy0">,</span> <span class="st_h">'d'</span><span class="br0">&#93;</span> <span class="br0">&#41;</span><span class="sy0">-&gt;</span><span class="me1">toJson</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></div></div></div></div></div></div></div>






<p>Like the PHP <code>json_encode()</code> method, it accepts a parameter for passing options that are used during encoding the elements. There are two that you may find extremely useful:</p>





<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="php"><pre class="de1">map<span class="br0">&#40;</span> <span class="br0">&#91;</span><span class="st_h">'a'</span><span class="sy0">,</span> <span class="st_h">'b'</span><span class="sy0">,</span> <span class="br0">&#91;</span><span class="st_h">'c'</span><span class="sy0">,</span> <span class="st_h">'d'</span><span class="br0">&#93;</span> <span class="br0">&#41;</span><span class="sy0">-&gt;</span><span class="me1">toJson</span><span class="br0">&#40;</span> JSON_FORCE_OBJECT<span class="sy0">|</span>JSON_HEX_QUOT <span class="br0">&#41;</span><span class="sy0">;</span></pre></div></div></div></div></div></div></div>






<p><code>JSON_FORCE_OBJECT</code> always creates <code>{}</code>, even for empty lists to avoid being encoded as <code>[]</code>. If you add JSON output to HTML data attributes for storing something you need for dynamic Javascript features later on, <code>JSON_HEX_QUOT</code> saves you from generating invalid HTML.</p>



<h2>walk(): Visit each value in a multi-dimensional array</h2>



<p>You receive a multi-dimensional array from an HTML form and want to make sure that all values are of a certain type or doesn&#8217;t contain HTML tags? Then, the walk() method of the PHP Map object is your friend:</p>





<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="php"><pre class="de1">map<span class="br0">&#40;</span> <span class="br0">&#91;</span><span class="st_h">'a'</span><span class="sy0">,</span> <span class="st_h">'b'</span><span class="sy0">,</span> <span class="br0">&#91;</span><span class="st_h">'c'</span><span class="sy0">,</span> <span class="st_h">'&lt;b&gt;d&lt;/b&gt;'</span><span class="br0">&#93;</span> <span class="br0">&#41;</span><span class="sy0">-&gt;</span><span class="me1">walk</span><span class="br0">&#40;</span> <span class="kw2">function</span><span class="br0">&#40;</span> <span class="sy0">&amp;</span><span class="re0">$val</span> <span class="br0">&#41;</span> <span class="br0">&#123;</span>
    <span class="re0">$val</span> <span class="sy0">=</span> <span class="kw3">strip_tags</span><span class="br0">&#40;</span> <span class="re0">$val</span> <span class="br0">&#41;</span><span class="sy0">;</span>
<span class="br0">&#125;</span> <span class="br0">&#41;</span><span class="sy0">;</span></pre></div></div></div></div></div></div></div>






<p>You can also create a mapping based on the list you pass as second parameter:</p>





<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="php"><pre class="de1"><span class="re0">$mapping</span> <span class="sy0">=</span> <span class="br0">&#91;</span><span class="nu0">1</span> <span class="sy0">=&gt;</span> <span class="st_h">'one'</span><span class="sy0">,</span> <span class="nu0">2</span> <span class="sy0">=&gt;</span> <span class="st_h">'two'</span><span class="sy0">,</span> <span class="nu0">3</span> <span class="sy0">=&gt;</span> <span class="st_h">'three'</span><span class="sy0">,</span> <span class="nu0">4</span> <span class="sy0">=&gt;</span> <span class="st_h">'four'</span><span class="br0">&#93;</span><span class="sy0">;</span>
&nbsp;
map<span class="br0">&#40;</span> <span class="br0">&#91;</span><span class="nu0">1</span><span class="sy0">,</span> <span class="nu0">2</span><span class="sy0">,</span> <span class="br0">&#91;</span><span class="nu0">3</span><span class="sy0">,</span> <span class="nu0">4</span><span class="br0">&#93;</span> <span class="br0">&#41;</span><span class="sy0">-&gt;</span><span class="me1">walk</span><span class="br0">&#40;</span> <span class="kw2">function</span><span class="br0">&#40;</span> <span class="sy0">&amp;</span><span class="re0">$val</span><span class="sy0">,</span> <span class="re0">$key</span><span class="sy0">,</span> <span class="re0">$data</span> <span class="br0">&#41;</span> <span class="br0">&#123;</span>
    <span class="re0">$val</span> <span class="sy0">=</span> <span class="re0">$data</span><span class="br0">&#91;</span><span class="re0">$val</span><span class="br0">&#93;</span> ?? <span class="re0">$val</span><span class="sy0">;</span>
<span class="br0">&#125;</span><span class="sy0">,</span> <span class="re0">$mapping</span> <span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
<span class="co1">// Result equals</span>
map<span class="br0">&#40;</span> <span class="br0">&#91;</span><span class="st_h">'one'</span><span class="sy0">,</span> <span class="st_h">'two'</span><span class="sy0">,</span> <span class="br0">&#91;</span><span class="st_h">'three'</span><span class="sy0">,</span> <span class="st_h">'four'</span><span class="br0">&#93;</span><span class="br0">&#93;</span> <span class="br0">&#41;</span></pre></div></div></div></div></div></div></div>






<h2>method(): Register your own methods</h2>



<p>The best of all comes last: You can extend the PHP Map object by your own methods! This is extremely handy if you need the same code several times and different places. To register your own method, just do this:</p>





<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="php"><pre class="de1">\Aimeos\Map<span class="sy0">::</span><span class="me2">method</span><span class="br0">&#40;</span> <span class="st_h">'strrev'</span><span class="sy0">,</span> <span class="kw2">function</span><span class="br0">&#40;</span> <span class="re0">$sep</span> <span class="br0">&#41;</span> <span class="br0">&#123;</span>
    <span class="kw1">return</span> <span class="kw3">strrev</span><span class="br0">&#40;</span> <span class="kw3">join</span><span class="br0">&#40;</span> <span class="st_h">'-'</span><span class="sy0">,</span> <span class="re0">$this</span><span class="sy0">-&gt;</span><span class="kw3">list</span> <span class="br0">&#41;</span> <span class="br0">&#41;</span><span class="sy0">;</span>
<span class="br0">&#125;</span> <span class="br0">&#41;</span><span class="sy0">;</span></pre></div></div></div></div></div></div></div>






<p>Your closure function has access to the internal array of elements using <code>$this-&gt;list</code> and you can read and/or modify that internal array of the Map object. You can use your new method the same way as any other method of the Map object afterwards:</p>





<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="php"><pre class="de1">map<span class="br0">&#40;</span> <span class="br0">&#91;</span><span class="st_h">'a'</span><span class="sy0">,</span> <span class="st_h">'b'</span><span class="br0">&#93;</span> <span class="br0">&#41;</span><span class="sy0">-&gt;</span><span class="kw3">strrev</span><span class="br0">&#40;</span> <span class="st_h">'-'</span> <span class="br0">&#41;</span><span class="sy0">;</span>
<span class="co1">// returns &quot;b-a&quot;</span></pre></div></div></div></div></div></div></div>






<h2>Conclusion</h2>



<p>The PHP Map object offers some great methods that can simplify your code drastically and you will never want to miss them any more. Especially the possibility to register own methods to extend the Map object dynamically gives your great power in a few lines of code.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://aimeos.org/tips/php-advanced-map-methods/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>PHP: Array to Map</title>
		<link>https://aimeos.org/tips/php-array-to-map/</link>
					<comments>https://aimeos.org/tips/php-array-to-map/#respond</comments>
		
		<dc:creator><![CDATA[aimeos]]></dc:creator>
		<pubDate>Sat, 07 Dec 2019 18:23:33 +0000</pubDate>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[array]]></category>
		<category><![CDATA[map]]></category>
		<guid isPermaLink="false">https://aimeos.org/tips/?p=490</guid>

					<description><![CDATA[Arrays are the working horse of PHP, the programming language used by the vast majority of web applications. An array seems to be incredible simple to use but things get complicated and ugly when PHP functions for array manipulation come<span class="ellipsis">&#8230;</span><div class="read-more"><a href="https://aimeos.org/tips/php-array-to-map/">Read more <span class="screen-reader-text">PHP: Array to Map</span><span class="meta-nav"> &#8250;</span></a></div><!-- end of .read-more -->]]></description>
										<content:encoded><![CDATA[
<div class="wp-block-image"><figure class="aligncenter"><img width="1198" height="629" src="https://aimeos.org/tips/wp-content/uploads/2019/12/php-array-map-1.png" alt="PHP Array to Map" class="wp-image-493" srcset="https://aimeos.org/tips/wp-content/uploads/2019/12/php-array-map-1.png 1198w, https://aimeos.org/tips/wp-content/uploads/2019/12/php-array-map-1-300x158.png 300w, https://aimeos.org/tips/wp-content/uploads/2019/12/php-array-map-1-768x403.png 768w, https://aimeos.org/tips/wp-content/uploads/2019/12/php-array-map-1-1024x538.png 1024w, https://aimeos.org/tips/wp-content/uploads/2019/12/php-array-map-1-100x53.png 100w, https://aimeos.org/tips/wp-content/uploads/2019/12/php-array-map-1-150x79.png 150w, https://aimeos.org/tips/wp-content/uploads/2019/12/php-array-map-1-200x105.png 200w, https://aimeos.org/tips/wp-content/uploads/2019/12/php-array-map-1-450x236.png 450w, https://aimeos.org/tips/wp-content/uploads/2019/12/php-array-map-1-600x315.png 600w, https://aimeos.org/tips/wp-content/uploads/2019/12/php-array-map-1-900x473.png 900w" sizes="(max-width: 1198px) 100vw, 1198px" /></figure></div>



<p>Arrays are the working horse of PHP, the programming language used by the vast majority of web applications. An array seems to be incredible simple to use but things get <strong>complicated and ugly</strong> when PHP functions for <strong>array manipulation</strong> come into play. Are you tired of hard to read code with excessive error handling too? Then maps can be the answer.</p>



<ul><li><a href="https://github.com/aimeos/map">Documentation at Github</a></li><li><a href="https://packagist.org/packages/aimeos/map">Composer package at Packagist</a></li></ul>



<span id="more-490"></span>



<h2>Why?</h2>



<p>Here&#8217;s a common example of how array manipulation is done in most PHP code:</p>





<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="php"><pre class="de1"><span class="re0">$list</span> <span class="sy0">=</span> <span class="br0">&#91;</span><span class="br0">&#91;</span><span class="st_h">'id'</span> <span class="sy0">=&gt;</span> <span class="st_h">'one'</span><span class="sy0">,</span> <span class="st_h">'value'</span> <span class="sy0">=&gt;</span> <span class="st_h">'value1'</span><span class="br0">&#93;</span><span class="sy0">,</span> <span class="br0">&#91;</span><span class="st_h">'id'</span> <span class="sy0">=&gt;</span> <span class="st_h">'two'</span><span class="sy0">,</span> <span class="st_h">'value'</span> <span class="sy0">=&gt;</span> <span class="st_h">'value2'</span><span class="br0">&#93;</span><span class="sy0">,</span> <span class="kw4">null</span><span class="br0">&#93;</span><span class="sy0">;</span>
&nbsp;
<span class="re0">$list</span><span class="br0">&#91;</span><span class="br0">&#93;</span> <span class="sy0">=</span> <span class="br0">&#91;</span><span class="st_h">'id'</span> <span class="sy0">=&gt;</span> <span class="st_h">'three'</span><span class="sy0">,</span> <span class="st_h">'value'</span> <span class="sy0">=&gt;</span> <span class="st_h">'value3'</span><span class="br0">&#93;</span><span class="sy0">;</span>    <span class="co1">// add element</span>
<span class="kw3">unset</span><span class="br0">&#40;</span> <span class="re0">$list</span><span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span> <span class="br0">&#41;</span><span class="sy0">;</span>                                   <span class="co1">// remove element</span>
<span class="re0">$list</span> <span class="sy0">=</span> <span class="kw3">array_filter</span><span class="br0">&#40;</span> <span class="re0">$list</span> <span class="br0">&#41;</span><span class="sy0">;</span>                       <span class="co1">// remove empty values</span>
<span class="kw3">sort</span><span class="br0">&#40;</span> <span class="re0">$list</span> <span class="br0">&#41;</span><span class="sy0">;</span>                                       <span class="co1">// sort elements</span>
<span class="re0">$pairs</span> <span class="sy0">=</span> array_column<span class="br0">&#40;</span> <span class="re0">$list</span><span class="sy0">,</span> <span class="st_h">'value'</span><span class="sy0">,</span> <span class="st_h">'id'</span> <span class="br0">&#41;</span><span class="sy0">;</span>       <span class="co1">// create ['three' =&gt; 'value3']</span>
<span class="re0">$value</span> <span class="sy0">=</span> <span class="kw3">reset</span><span class="br0">&#40;</span> <span class="re0">$pairs</span> <span class="br0">&#41;</span> ?<span class="sy0">:</span> <span class="kw4">null</span><span class="sy0">;</span>                    <span class="co1">// return first value</span></pre></div></div></div></div></div></div></div>






<p>It adds/removes elements, sorts and transforms the content and retrieves the first element. You can&#8217;t write that shorter or more elegant and moreover, you need to check almost all array functions for errors.</p>



<h2>Using maps</h2>



<p>The <em>map</em> composer package offers an easy API comparable to jQuery or Laravel collections:</p>



<p><code>composer req aimeos/map</code></p>



<p>When using the Map object, you can do the same as above more elegant with less code:</p>





<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="php"><pre class="de1"><span class="re0">$list</span> <span class="sy0">=</span> <span class="br0">&#91;</span><span class="br0">&#91;</span><span class="st_h">'id'</span> <span class="sy0">=&gt;</span> <span class="st_h">'one'</span><span class="sy0">,</span> <span class="st_h">'value'</span> <span class="sy0">=&gt;</span> <span class="st_h">'value1'</span><span class="br0">&#93;</span><span class="sy0">,</span> <span class="br0">&#91;</span><span class="st_h">'id'</span> <span class="sy0">=&gt;</span> <span class="st_h">'two'</span><span class="sy0">,</span> <span class="st_h">'value'</span> <span class="sy0">=&gt;</span> <span class="st_h">'value2'</span><span class="br0">&#93;</span><span class="sy0">,</span> <span class="kw4">null</span><span class="br0">&#93;</span><span class="sy0">;</span>
&nbsp;
<span class="re0">$value</span> <span class="sy0">=</span> map<span class="br0">&#40;</span> <span class="re0">$list</span> <span class="br0">&#41;</span>                                <span class="co1">// create Map</span>
    <span class="sy0">-&gt;</span><span class="me1">push</span><span class="br0">&#40;</span> <span class="br0">&#91;</span><span class="st_h">'id'</span> <span class="sy0">=&gt;</span> <span class="st_h">'three'</span><span class="sy0">,</span> <span class="st_h">'value'</span> <span class="sy0">=&gt;</span> <span class="st_h">'value3'</span><span class="br0">&#93;</span> <span class="br0">&#41;</span> <span class="co1">// add element</span>
    <span class="sy0">-&gt;</span><span class="me1">remove</span><span class="br0">&#40;</span> <span class="nu0">0</span> <span class="br0">&#41;</span>                                    <span class="co1">// remove element</span>
    <span class="sy0">-&gt;</span><span class="me1">filter</span><span class="br0">&#40;</span><span class="br0">&#41;</span>                                       <span class="co1">// remove empty values</span>
    <span class="sy0">-&gt;</span><span class="kw3">sort</span><span class="br0">&#40;</span><span class="br0">&#41;</span>                                         <span class="co1">// sort elements</span>
    <span class="sy0">-&gt;</span><span class="me1">col</span><span class="br0">&#40;</span> <span class="st_h">'value'</span><span class="sy0">,</span> <span class="st_h">'id'</span> <span class="br0">&#41;</span>                           <span class="co1">// create ['three' =&gt; 'value3']</span>
    <span class="sy0">-&gt;</span><span class="me1">first</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>                                       <span class="co1">// return first value</span></pre></div></div></div></div></div></div></div>






<p>And contrary to PHP arrays, you don&#8217;t have to care about error handling because either, there are no errors possible or the Map object will throw an exception if something is really wrong.</p>



<p>Of course, you can use the Map object still like a plain PHP array:</p>





<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="php"><pre class="de1"><span class="re0">$map</span><span class="br0">&#91;</span><span class="br0">&#93;</span> <span class="sy0">=</span> <span class="br0">&#91;</span><span class="st_h">'id'</span> <span class="sy0">=&gt;</span> <span class="st_h">'three'</span><span class="sy0">,</span> <span class="st_h">'value'</span> <span class="sy0">=&gt;</span> <span class="st_h">'value3'</span><span class="br0">&#93;</span><span class="sy0">;</span>
<span class="re0">$value</span> <span class="sy0">=</span> <span class="re0">$map</span><span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span><span class="sy0">;</span>
<span class="kw3">count</span><span class="br0">&#40;</span> <span class="re0">$map</span> <span class="br0">&#41;</span><span class="sy0">;</span>
<span class="kw1">foreach</span><span class="br0">&#40;</span> <span class="re0">$map</span> <span class="kw1">as</span> <span class="re0">$key</span> <span class="sy0">=&gt;</span> value <span class="br0">&#41;</span><span class="sy0">;</span></pre></div></div></div></div></div></div></div>






<p>In addition, Map objects allow you to pass anonymous functions to a lot of methods. Thus, you can process and transform the elements according to your current needs, e.g. using the <code>each()</code> method:</p>





<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="php"><pre class="de1"><span class="re0">$map</span><span class="sy0">-&gt;</span><span class="kw3">each</span><span class="br0">&#40;</span> <span class="kw2">function</span><span class="br0">&#40;</span> <span class="re0">$val</span><span class="sy0">,</span> <span class="re0">$key</span> <span class="br0">&#41;</span> <span class="br0">&#123;</span>
    <span class="kw1">echo</span> <span class="re0">$key</span> <span class="sy0">.</span> <span class="st_h">': '</span> <span class="sy0">.</span> <span class="re0">$val</span><span class="sy0">;</span>
<span class="br0">&#125;</span> <span class="br0">&#41;</span><span class="sy0">;</span></pre></div></div></div></div></div></div></div>






<p>You can even extend Maps dynamically by own methods. This is especially useful if you need a transformation of the Map elements more often and at several places of your code:</p>





<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="php"><pre class="de1">Map<span class="sy0">::</span><span class="me2">method</span><span class="br0">&#40;</span> <span class="st_h">'strrev'</span><span class="sy0">,</span> <span class="kw2">function</span><span class="br0">&#40;</span> <span class="re0">$sep</span> <span class="br0">&#41;</span> <span class="br0">&#123;</span>
    <span class="kw1">return</span> <span class="kw3">strrev</span><span class="br0">&#40;</span> <span class="kw3">join</span><span class="br0">&#40;</span> <span class="st_h">'-'</span><span class="sy0">,</span> <span class="re0">$this</span><span class="sy0">-&gt;</span><span class="kw3">list</span> <span class="br0">&#41;</span> <span class="br0">&#41;</span><span class="sy0">;</span>
<span class="br0">&#125;</span> <span class="br0">&#41;</span><span class="sy0">;</span>
Map<span class="sy0">::</span><span class="me2">from</span><span class="br0">&#40;</span> <span class="br0">&#91;</span><span class="st_h">'a'</span><span class="sy0">,</span> <span class="st_h">'b'</span><span class="br0">&#93;</span> <span class="br0">&#41;</span><span class="sy0">-&gt;</span><span class="kw3">strrev</span><span class="br0">&#40;</span> <span class="st_h">'-'</span> <span class="br0">&#41;</span><span class="sy0">;</span></pre></div></div></div></div></div></div></div>






<p>The best part is using a Map like a jQuery object, where methods are applied to all objects of the Map. Then, you can create expressive code in one line:</p>





<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="php"><pre class="de1"><span class="kw2">class</span> MyClass <span class="br0">&#123;</span>
    <span class="kw2">private</span> <span class="re0">$code</span><span class="sy0">;</span>
    <span class="kw2">private</span> <span class="re0">$status</span><span class="sy0">;</span>
&nbsp;
    <span class="kw2">public</span> <span class="kw2">function</span> __construct<span class="br0">&#40;</span> <span class="re0">$code</span> <span class="br0">&#41;</span> <span class="br0">&#123;</span> <span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">code</span> <span class="sy0">=</span> <span class="re0">$code</span><span class="sy0">;</span> <span class="br0">&#125;</span>
    <span class="kw2">public</span> <span class="kw2">function</span> setStatus<span class="br0">&#40;</span> <span class="re0">$s</span> <span class="br0">&#41;</span> <span class="br0">&#123;</span> <span class="re0">$this</span><span class="sy0">-&gt;</span><span class="kw3">stat</span> <span class="sy0">=</span> <span class="re0">$s</span><span class="sy0">;</span> <span class="kw1">return</span> <span class="re0">$this</span><span class="sy0">;</span> <span class="br0">&#125;</span>
    <span class="kw2">public</span> <span class="kw2">function</span> getCode<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span> <span class="kw1">return</span> <span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">code</span><span class="sy0">;</span> <span class="br0">&#125;</span>
<span class="br0">&#125;</span>
&nbsp;
<span class="re0">$objects</span> <span class="sy0">=</span> Map<span class="sy0">::</span><span class="me2">from</span><span class="br0">&#40;</span> <span class="br0">&#91;</span><span class="st_h">'a'</span> <span class="sy0">=&gt;</span> <span class="kw2">new</span> MyClass<span class="br0">&#40;</span> <span class="st_h">'x'</span> <span class="br0">&#41;</span><span class="sy0">,</span> <span class="st_h">'b'</span> <span class="sy0">=&gt;</span> <span class="kw2">new</span> MyClass<span class="br0">&#40;</span> <span class="st_h">'y'</span> <span class="br0">&#41;</span><span class="br0">&#93;</span> <span class="br0">&#41;</span><span class="sy0">;</span>
<span class="re0">$result</span> <span class="sy0">=</span> <span class="re0">$objects</span><span class="sy0">-&gt;</span><span class="me1">setStatus</span><span class="br0">&#40;</span> <span class="nu0">1</span> <span class="br0">&#41;</span><span class="sy0">-&gt;</span><span class="me1">getCode</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">-&gt;</span><span class="me1">toArray</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></div></div></div></div></div></div></div>






<p>The example will call <code>setStatus( 1 )</code> on all objects and creates a new Map with the returned values. Because <code>setStatus()</code> returns the same object (<code>$this</code>), we can apply another method on all objects afterwards (<code>getCode()</code>). The results of <code>getCode()</code> is wrapped in a Map object again and <code>toArray()</code> returns a plain PHP array which consists of:</p>





<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="php"><pre class="de1"><span class="br0">&#91;</span><span class="st_h">'a'</span> <span class="sy0">=&gt;</span> <span class="st_h">'x'</span><span class="sy0">,</span> <span class="st_h">'b'</span> <span class="sy0">=&gt;</span> <span class="st_h">'y'</span><span class="br0">&#93;</span></pre></div></div></div></div></div></div></div>






<h2>Available methods</h2>



<p>The Map object contains methods for almost all array functions available and more like collapse(), flat(), toJson() or methods found in the Javascript Array prototype. Here&#8217;s a list of its methods and for documentation, have a look at the <a href="https://github.com/aimeos/map#methods">Map readme</a> at GitHub where you can also check the code.</p>



<ul><li><strong>function is_map()</strong>&nbsp;: Tests if the variable is a map object</li><li><strong>function map()</strong> : Creates a new map from elements</li><li><strong>arsort()</strong> : Reverse sort elements with keys</li><li><strong>asort()</strong> : Sort elements with keys</li><li><strong>chunk()</strong> : Splits the map into chunks</li><li><strong>clear()</strong> : Removes all elements</li><li><strong>col()</strong> : Creates a key/value mapping</li><li><strong>collapse()</strong> : Collapses multi-dimensional elements</li><li><strong>concat()</strong> : Combines the elements</li><li><strong>copy()</strong> : Creates a new copy</li><li><strong>count()</strong> : Returns the number of elements</li><li><strong>diff()</strong> : Returns the missing elements</li><li><strong>diffAssoc()</strong> : Returns the missing elements and checks keys</li><li><strong>diffKeys()</strong> : Returns the missing elements by keys</li><li><strong>each()</strong> : Applies a callback to each element</li><li><strong>empty()</strong> : Tests if map is empty</li><li><strong>equals()</strong> : Tests if map contents are equal</li><li><strong>filter()</strong> : Applies a filter to the map elements</li><li><strong>find()</strong> : Returns the first matching element</li><li><strong>first()</strong> : Returns the first element</li><li><strong>firstKey()</strong>&nbsp;: Returns the first key</li><li><strong>flip()</strong> : Exchanges keys with their values</li><li><strong>flat()</strong> : Flattens multi-dimensional elements</li><li><strong>from()</strong> : Creates a new map from passed elements</li><li><strong>get()</strong> : Returns an element by key</li><li><strong>has()</strong> : Tests if a key exists</li><li><strong>in()</strong> : Tests if element is included</li><li><strong>includes()</strong> : Tests if element is included</li><li><strong>intersect()</strong> : Returns the shared elements</li><li><strong>intersectAssoc()</strong> : Returns the shared elements and checks keys</li><li><strong>intersectKeys()</strong> : Returns the shared elements by keys</li><li><strong>isEmpty()</strong> : Tests if map is empty</li><li><strong>join()</strong> : Returns concatenated elements as string</li><li><strong>keys()</strong> : Returns the keys</li><li><strong>krsort()</strong> : Reverse sort elements by keys</li><li><strong>ksort()</strong> : Sort elements by keys</li><li><strong>last()</strong> : Returns the last element</li><li><strong>lastKey()</strong>&nbsp;: Returns the last key</li><li><strong>map()</strong> : Applies a callback to each element and returns the results</li><li><strong>merge()</strong> : Combines elements overwriting existing ones</li><li><strong>method()</strong> : Registers a custom method</li><li><strong>pipe()</strong> : Applies a callback to the map</li><li><strong>pop()</strong> : Returns and removes the last element</li><li><strong>pull()</strong> : Returns and removes an element by key</li><li><strong>push()</strong> : Adds an element to the end</li><li><strong>random()</strong> : Returns random elements</li><li><strong>reduce()</strong> : Computes a value for the map content</li><li><strong>remove()</strong> : Removes an element by key</li><li><strong>replace()</strong> : Replaces elements recursively</li><li><strong>reverse()</strong> : Reverses the array order</li><li><strong>rsort()</strong> : Reverse sort elements</li><li><strong>search()</strong> : Find the key of an element</li><li><strong>set()</strong> : Overwrites an element</li><li><strong>shift()</strong> : Returns and removes the first element</li><li><strong>shuffle()</strong> : Randomizes the element order</li><li><strong>slice()</strong> : Returns a slice of the map</li><li><strong>sort()</strong> : Sorts elements</li><li><strong>split()</strong> : Splits a string into map elements</li><li><strong>splice()</strong> : Replaces a slice by new elements</li><li><strong>toArray()</strong> : Returns the plain array</li><li><strong>toJson()</strong> : Returns the elements in JSON format</li><li><strong>uasort()</strong> : Sorts elements with keys using callback</li><li><strong>uksort()</strong> : Sorts elements by keys using callback</li><li><strong>union()</strong> : Combines the element without overwriting</li><li><strong>unique()</strong> : Returns unique elements</li><li><strong>unshift()</strong> : Adds an element at the beginning</li><li><strong>usort()</strong> : Sorts elements using callback</li><li><strong>values()</strong> : Returns all elements with new keys</li></ul>



<p>Again, the <a href="https://github.com/aimeos/map#methods">Map documentation</a> offers descriptions, explains parameters/return values and has examples for each method. Some methods are even better documented than the corresponding PHP array function.</p>



<h2>Conclusion</h2>



<p>Map objects are an easy to use and elegant way to handle PHP arrays. After using it for a while you won&#8217;t want to remember the times before. If you&#8217;ve already worked with jQuery and like it&#8217;s simplicity, you will feel like home when using appropriate lists of objects in your application.</p>



<p>As the Map methods are using the native array functions or are highly optimized, it&#8217;s also save to use them in large scale applications. The documentation contains a section about the <a href="https://github.com/aimeos/map#performance">Map performance</a> and hints to avoid performance bottlenecks.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://aimeos.org/tips/php-array-to-map/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Modern PHP applications up to 110x slower on network storage</title>
		<link>https://aimeos.org/tips/modern-php-applications-up-to-110x-slower-on-network-storage/</link>
					<comments>https://aimeos.org/tips/modern-php-applications-up-to-110x-slower-on-network-storage/#comments</comments>
		
		<dc:creator><![CDATA[aimeos]]></dc:creator>
		<pubDate>Fri, 15 Apr 2016 12:22:07 +0000</pubDate>
				<category><![CDATA[PHP]]></category>
		<guid isPermaLink="false">https://aimeos.org/tips/?p=160</guid>

					<description><![CDATA[Modern PHP applications consists of thousands of PHP files. Even if your own set of files is small, most of the functionality is nowadays provided by 3rd party libraries. Especially composer made it simpler than never before to integrate external<span class="ellipsis">&#8230;</span><div class="read-more"><a href="https://aimeos.org/tips/modern-php-applications-up-to-110x-slower-on-network-storage/">Read more <span class="screen-reader-text">Modern PHP applications up to 110x slower on network storage</span><span class="meta-nav"> &#8250;</span></a></div><!-- end of .read-more -->]]></description>
										<content:encoded><![CDATA[<p><a href="https://aimeos.org/tips/wp-content/uploads/2016/04/performance-loss-small.jpg"><img class="aligncenter size-full wp-image-161" src="https://aimeos.org/tips/wp-content/uploads/2016/04/performance-loss-small.jpg" alt="performance-loss-small" width="800" height="600" srcset="https://aimeos.org/tips/wp-content/uploads/2016/04/performance-loss-small.jpg 800w, https://aimeos.org/tips/wp-content/uploads/2016/04/performance-loss-small-300x225.jpg 300w, https://aimeos.org/tips/wp-content/uploads/2016/04/performance-loss-small-768x576.jpg 768w, https://aimeos.org/tips/wp-content/uploads/2016/04/performance-loss-small-100x75.jpg 100w, https://aimeos.org/tips/wp-content/uploads/2016/04/performance-loss-small-150x113.jpg 150w, https://aimeos.org/tips/wp-content/uploads/2016/04/performance-loss-small-200x150.jpg 200w, https://aimeos.org/tips/wp-content/uploads/2016/04/performance-loss-small-450x338.jpg 450w, https://aimeos.org/tips/wp-content/uploads/2016/04/performance-loss-small-600x450.jpg 600w" sizes="(max-width: 800px) 100vw, 800px" /></a></p>
<p>Modern PHP applications consists of thousands of PHP files. Even if your own set of files is small, most of the functionality is nowadays provided by 3rd party libraries. Especially composer made it simpler than never before to integrate external libraries and full stack frameworks like Laravel or Symfony contains a lot of them. The <a href="https://aimeos.org/">Aimeos e-commerce components</a> are not different in this case since this kind of code reuse is the best thing since sliced bread <img src="https://s.w.org/images/core/emoji/13.0.1/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<p><span id="more-160"></span></p>
<h2>Bad old days and brave new world</h2>
<p>The downside is that a single request have to touch a lot of PHP files, sometimes up to several hundred. In the &#8220;bad old days&#8221;, each file must be read from the disk, parsed into byte code and executed by the PHP interpreter if byte code caches like APC wasn&#8217;t installed. That took a lot of time and PHP applications could require up to several seconds to finish a request.</p>
<p>Since PHP 5.5, performance improved very much, mostly by the integrated OPcode cache, since PHP7 also by various optimizations inside the PHP interpreter itself. Now, request times of even big PHP applications can be only several 100ms or below. PHP applications can be almost as fast as Java one. Great stuff!</p>
<h2>When things turn wrong</h2>
<p>There&#8217;s only one problem PHP developers and administrators don&#8217;t really think about: The applications are only fast as long as the file system the files are stored is fast too! We&#8217;re not talking about the sequential read or write performance, which can be fast on network file systems too. It&#8217;s the time required for file access that matters if your application consists of several thousand files!</p>
<h3>OPcache</h3>
<p>Why the file access you might wondering? The OPcache keeps the files in memory so there&#8217;s no file access at all? Wrong! Even if you configured the available memory of the OPcache to be big enough for all files, it checks for file modifications regularly. By default, this check is executed every two seconds. A better value would be 60 seconds or more:</p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="ini"><pre class="de1">opcache.revalidate_freq <span class="sy0">=</span><span class="re2"> 60</span></pre></div></div></div></div></div></div></div>


<p>Things will get even worse. For every part of the file path, the meta data is retrieved by the file system. The path &#8220;/var/www/html/index.php&#8221; will result in requests for &#8220;/var&#8221;, &#8220;/var/wwww&#8221;, &#8220;/var/www/html&#8221; and &#8220;/var/www/html/index.php&#8221;. You see, this can result in a lot of request for hundreds of files stored deep down in a directory tree.</p>
<h3>Real path cache</h3>
<p>PHP has a feature called &#8220;real path cache&#8221; that should mitigate the problem. The thought about the this cache is to reduce the amount of file system requests by storing the absolute path of the requested files. So far so good but it&#8217;s value is 16KB by default and this is ridiculously low for modern PHP applications. This results in a constant trashing of the cached entries and renders the cache useless with this size. To avoid this, you should start and test with values of 128KB and more:</p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="ini"><pre class="de1"><span class="re1">realpath_cache_size</span> <span class="sy0">=</span><span class="re2"> 128KB</span></pre></div></div></div></div></div></div></div>


<h2>The network stoage disaster</h2>
<p>So, where&#8217;s the 110x performance loss? Well, retrieving file meta data is fast when it&#8217;s already in the cache of the operating system and don&#8217;t have to be revalidated. Then, it doesn&#8217;t matter much if the OPcache and real path cache settings are misconfigured.</p>
<p>For our tests, we&#8217;ve used the <a href="https://github.com/aimeos/aimeos-core">Aimeos Core</a> plus the required libraries and extensions (ca. 6500 files and directories) as reference and executed the following command in the Aimeos directory:</p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="bash"><pre class="de1"><span class="co4"># </span><span class="kw1">time</span> <span class="br0">&#40;</span><span class="kw2">find</span> . <span class="sy0">&amp;</span>gt; <span class="sy0">/</span>dev<span class="sy0">/</span>null<span class="br0">&#41;</span></pre></div></div></div></div></div></div></div>


<h3>Ext4</h3>
<p>Let&#8217;s test the meta data performance of an Ext4 file system on a local hard disk.</p>
<p>First test:</p>
<pre>real    0m2.722s
user    0m0.017s
sys     0m0.130s
</pre>
<p>Subsequent tests:</p>
<pre>real    0m0.043s
user    0m0.003s
sys     0m0.040s
</pre>
<p>The first time retrieving the meta data of all files and directories from the hard disk lasted 2.722 seconds. If the data is cached by the operating system, only 0.043 seconds are needed.</p>
<h3>NFS</h3>
<p>Now we did the same for NFS, the standard Unix network file system:</p>
<p>First test:</p>
<pre>real    0m4.197s
user    0m0.032s
sys     0m0.188s
</pre>
<p>Subsequent tests:</p>
<pre>real    0m0.490s
user    0m0.019s
sys     0m0.080s
</pre>
<p>The first time, it takes almost 1.5x as long than from a local hard disk and afterwards it needs even 10x longer. Thus, performance of PHP applications over NFS will severely suffer!</p>
<h3>GlusterFS</h3>
<p>Have a look at GlusterFS, another network file system:</p>
<p>First test:</p>
<pre>real    0m9.031s
user    0m0.045s
sys     0m0.176s
</pre>
<p>Subsequent tests:</p>
<pre>real    0m4.769s
user    0m0.052s
sys     0m0.156s
</pre>
<p>Not only that the first time it took more then three times longer than from a local hard disk, the subsequent test have shown a more than 110x worse performance compared to the local hard disk. You can imagine that this will lead to response times of several seconds!</p>
<h2>Conclusions</h2>
<p>The test results made clear that storing the files of a PHP application on a network storage is really a bad idea. It will make more than a noticeable difference and results in response times which are extremely bad when compared to applications stored on local hard disks.</p>
<p>If you have no other chance than using a network storage, you should at least optimize and test the OPcache and real path cache settings to mitigate the problem. If you use optimal settings, you can decrease the request time penalty to only 2-4 times of a local disk. But it will make a big difference if your customers wait 0.5 or up to 4 seconds!</p>
]]></content:encoded>
					
					<wfw:commentRss>https://aimeos.org/tips/modern-php-applications-up-to-110x-slower-on-network-storage/feed/</wfw:commentRss>
			<slash:comments>4</slash:comments>
		
		
			</item>
	</channel>
</rss>
