<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/"><channel><title>Php on notes</title><link>https://unionsep.dev/tags/php/</link><description>Recent content in Php on notes</description><generator>Hugo -- 0.161.1</generator><language>en</language><lastBuildDate>Thu, 13 Apr 2017 16:23:09 +0900</lastBuildDate><atom:link href="https://unionsep.dev/tags/php/index.xml" rel="self" type="application/rss+xml"/><item><title>再帰的なarray_searchを作った</title><link>https://unionsep.dev/posts/2017/04/17/162309/</link><pubDate>Thu, 13 Apr 2017 16:23:09 +0900</pubDate><author>unionsep</author><guid>https://unionsep.dev/posts/2017/04/17/162309/</guid><description>&amp;lt;no value&amp;gt;</description><content type="text/html" mode="escaped"><![CDATA[<p>どもども</p>
<p>すっかり春な気候になってきて、フレッシュな方々を目にする機会が多くなりました。
フレッシュな感じに羨望の眼差しを向けながら、ここ4年ぐらい、ず〜っとPHPをメインに扱っています。</p>
<p>う〜ん、もともとず〜っとJava、Perlな感じの人で、敷居が低いと噂のPHPを横目に見てましたが、ソシャゲを扱うようになってPHPも扱うようになったんですが、もはや何を作るにしても、もうPHPでよくね？みたいな脳みそになってしまったのが良かったのか悪かったのか。。<br>
まぁ、アンチPHPな方もお見かけしますし、当然、僕自身もPHPのこの言語仕様はやだな〜って思ったりしたりすることもあります。
確かにレガシーなシステムを扱うときに、脳みそひねくり回さないとダメなときもあるし、<a href="https://secure.php.net/manual/ja/index.php">PHPマニュアル</a> 見てて、え、そうなの。。って思うときもあります。<br>
でも地雷を踏まない能力ってエンジニアに必要な能力の一つだったりするのかなぁって今は思っています。
そういう能力を養うコストと、PHP
の強力な文字列処理や配列処理の恩恵を受けるメリットを天秤にかけて、やっぱPHPで良いかなぁと思う次第です。。</p>
<hr>
<p>個人的なコラムはどうでもいいとして、僕がPHPを気に入っている面の一つが配列処理です。
<code>array_column</code> とか <code>usort</code> とかは超気にいってますが、 <code>array_search</code> が単一階層の配列しか検索してくれない。。
配列の中に設定項目を連想配列にして詰め込んで、特定の設定項目を探し出すっていうケース、ソシャゲでは結構あったんですが、ソシャゲから離れた今、またそういう要件に対峙する時が来ました。
あれ、こういうパターンって確か共通関数にしてたなぁって思ったので、はてブから「そろそろブログ書かない？」メールも来たので、筆を取る気になりました。</p>
<p>想定している連想配列は以下のような構造です。</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-php" data-lang="php"><span style="display:flex;"><span>$event <span style="color:#f92672">=</span> <span style="color:#66d9ef">array</span>(
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">array</span>(
</span></span><span style="display:flex;"><span>        <span style="color:#e6db74">&#39;start_date&#39;</span> <span style="color:#f92672">=&gt;</span> <span style="color:#e6db74">&#39;2017-01-01 00:00:00&#39;</span>,
</span></span><span style="display:flex;"><span>        <span style="color:#e6db74">&#39;end_date&#39;</span> <span style="color:#f92672">=&gt;</span> <span style="color:#e6db74">&#39;2017-03-31 23:59:59&#39;</span>,
</span></span><span style="display:flex;"><span>        <span style="color:#e6db74">&#39;key&#39;</span> <span style="color:#f92672">=&gt;</span> <span style="color:#e6db74">&#39;event_1&#39;</span>
</span></span><span style="display:flex;"><span>    ),
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">array</span>(
</span></span><span style="display:flex;"><span>        <span style="color:#e6db74">&#39;start_date&#39;</span> <span style="color:#f92672">=&gt;</span> <span style="color:#e6db74">&#39;2017-02-01 00:00:00&#39;</span>,
</span></span><span style="display:flex;"><span>        <span style="color:#e6db74">&#39;end_date&#39;</span> <span style="color:#f92672">=&gt;</span> <span style="color:#e6db74">&#39;2017-04-31 23:59:59&#39;</span>,
</span></span><span style="display:flex;"><span>        <span style="color:#e6db74">&#39;key&#39;</span> <span style="color:#f92672">=&gt;</span> <span style="color:#e6db74">&#39;event_2&#39;</span>
</span></span><span style="display:flex;"><span>    ),
</span></span><span style="display:flex;"><span>);
</span></span></code></pre></div><p><code>key</code> が <code>event_2</code> の要素番号を取りたいといった場面がよくありました。
ここで、 <code>array_search</code> でって思うのですが、このような配列の中に配列がある多重配列構造の場合、思った通りの動作をしてくれません。
そこで、こんな関数を作ってみました。</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#66d9ef">function</span> <span style="color:#a6e22e">array_search_recursive</span>($needle, $heystack)
</span></span><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>    $keys <span style="color:#f92672">=</span> <span style="color:#66d9ef">array</span>();
</span></span><span style="display:flex;"><span>    $func <span style="color:#f92672">=</span> <span style="color:#66d9ef">function</span> ($needle, $heystack) <span style="color:#66d9ef">use</span> (<span style="color:#f92672">&amp;</span>$func, <span style="color:#f92672">&amp;</span>$keys) {
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">foreach</span> ($heystack <span style="color:#66d9ef">as</span> $key <span style="color:#f92672">=&gt;</span> $val) {
</span></span><span style="display:flex;"><span>            <span style="color:#66d9ef">if</span> (<span style="color:#a6e22e">is_array</span>($val)) {
</span></span><span style="display:flex;"><span>                <span style="color:#66d9ef">if</span> ($func($needle, $val) <span style="color:#f92672">!==</span> <span style="color:#66d9ef">false</span>) {
</span></span><span style="display:flex;"><span>                    $keys[] <span style="color:#f92672">=</span> $key;
</span></span><span style="display:flex;"><span>                }
</span></span><span style="display:flex;"><span>            }
</span></span><span style="display:flex;"><span>            <span style="color:#66d9ef">if</span> ($needle <span style="color:#f92672">==</span> $val) {
</span></span><span style="display:flex;"><span>                $keys[] <span style="color:#f92672">=</span> $key;
</span></span><span style="display:flex;"><span>            }
</span></span><span style="display:flex;"><span>        }
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">return</span> <span style="color:#66d9ef">false</span>;
</span></span><span style="display:flex;"><span>    };
</span></span><span style="display:flex;"><span>    $func($needle, $heystack);
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> $keys;
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p><code>$needle</code> に検索したいキーワード、 <code>$heystack</code> に検索対象の配列を指定すると、検索に引っかかる要素番号を配列で返します。
検索に引っかからなかった場合は、空配列を返します。</p>
<p>これ、同じことを考えておられた方がいて、こちらのQiitaの記事を参考にしました。</p>
<aside class="cite-card">
    <img
      class="cite-card__image"
      src="https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-user-contents.imgix.net%2Fhttps%253A%252F%252Fcdn.qiita.com%252Fassets%252Fpublic%252Farticle-ogp-background-afbab5eb44e0b055cce1258705637a91.png%3Fixlib%3Drb-4.1.1%26w%3D1200%26blend64%3DaHR0cHM6Ly9xaWl0YS11c2VyLXByb2ZpbGUtaW1hZ2VzLmltZ2l4Lm5ldC9odHRwcyUzQSUyRiUyRnFpaXRhLWltYWdlLXN0b3JlLnMzLmFtYXpvbmF3cy5jb20lMkYwJTJGNDQzMTclMkZwcm9maWxlLWltYWdlcyUyRjE0NzM2ODk4NTY_aXhsaWI9cmItNC4xLjEmYXI9MSUzQTEmZml0PWNyb3AmbWFzaz1lbGxpcHNlJmJnPUZGRkZGRiZmbT1wbmczMiZzPWJiZTk0ZTU5MWIxZWE4MDFlYTNjNzQ2MDUzZjFkMDAz%26blend-x%3D120%26blend-y%3D467%26blend-w%3D82%26blend-h%3D82%26blend-mode%3Dnormal%26s%3D4abade8d2ca55a8177ee23ddf42aa93c?ixlib=rb-4.1.1&amp;w=1200&amp;fm=jpg&amp;mark64=aHR0cHM6Ly9xaWl0YS11c2VyLWNvbnRlbnRzLmltZ2l4Lm5ldC9-dGV4dD9peGxpYj1yYi00LjEuMSZ3PTk2MCZoPTMyNCZ0eHQ9UEhQJTNBJTIwJUU1JUE0JTlBJUU2JUFDJUExJUU1JTg1JTgzJUU5JTg1JThEJUU1JTg4JTk3JUUzJTgxJUE3YXJyYXlfc2VhcmNoJUUzJTgyJTkyJUU0JUJEJUJGJUUzJTgxJTg4JUUzJTgyJThCJUUzJTgyJTg4JUUzJTgxJTg2JUUzJTgxJUFCJUUzJTgxJTk5JUUzJTgyJThCJUU5JTk2JUEyJUU2JTk1JUIwJnR4dC1hbGlnbj1sZWZ0JTJDdG9wJnR4dC1jb2xvcj0lMjMxRTIxMjEmdHh0LWZvbnQ9SGlyYWdpbm8lMjBTYW5zJTIwVzYmdHh0LXNpemU9NTYmdHh0LXBhZD0wJnM9OWEzYzJjMDM2NzQxNWZlMThkNWMyZGUwZTdkYmU1MDQ&amp;mark-x=120&amp;mark-y=112&amp;blend64=aHR0cHM6Ly9xaWl0YS11c2VyLWNvbnRlbnRzLmltZ2l4Lm5ldC9-dGV4dD9peGxpYj1yYi00LjEuMSZ3PTgzOCZoPTU4JnR4dD0lNDB5b3Jrc3lvJnR4dC1jb2xvcj0lMjMxRTIxMjEmdHh0LWZvbnQ9SGlyYWdpbm8lMjBTYW5zJTIwVzYmdHh0LXNpemU9MzYmdHh0LXBhZD0wJnM9ZGVlODNlZmNmNmY3NWMxYjI3ODM2MWIxZGYzMTY2MjM&amp;blend-x=242&amp;blend-y=480&amp;blend-w=838&amp;blend-h=46&amp;blend-fit=crop&amp;blend-crop=left%2Cbottom&amp;blend-mode=normal&amp;s=4652f6c848b28b4b86c14a1db94454ff"
      alt=""
      loading="lazy"
    >

  <a href="http://qiita.com/yorksyo/items/4b0cbec7dcaec86907ab" target="_blank" rel="noopener noreferrer">
    <div class="cite-card__title">PHP: 多次元配列でarray_searchを使えるようにする関数</div>
      <div class="cite-card__description">
        1次元配列まで対応しているarray_searchを多次元配列に使えるようにする関数を作ってみました in_arrayとarray_valuesと多次元配列についてのコチラの投稿を…
      </div>

    <div class="cite-card__site">Qiita</div>
  </a>
</aside>

<p>記事では検索キーワードに引っかかった最初の要素番号を返却していますが、仰っている通り、引っかかった全ての要素番号を返却した方が、汎用性が高くなりそうだったので、少し改良しています。
とは言え、クロージャに配列を参照渡しして、引っかかったら配列に詰めるってとこしか改良していませんが。。^^;</p>
<hr>
<p>あと、 <code>start_date</code> が <code>2017-01-15 00:00:00</code> 以降の要素番号とかを取りたいとかもありますよね。<br>
そういう場合は、 <code>array_search_recursive</code> に関数を渡せるようにしてあげたら、もっとかっこよくなるかなぁ。
でも今回はそういう要件ではなかったので、脳みそ終了しました。</p>
<hr>
<p>クロージャを代入した変数を参照渡しして、検索対象が配列だった場合、どんどん下層まで検索していくので、リークしないか気になるとこですが、そこそこ使えるのではないでしょうか<br>
とは言え、 <code>array_column</code> で似たようなことできるよね〜とも思うのですが、実は開発環境は5.3みたいなとこあるのでは？</p>
<p>こういうの、Zephirで実装できたらかっこいいよねぇ</p>
<aside class="cite-card">
    <img
      class="cite-card__image"
      src="https://assets.phalcon.io/zephir/logo.png"
      alt=""
      loading="lazy"
    >

  <a href="https://zephir-lang.com/" target="_blank" rel="noopener noreferrer">
    <div class="cite-card__title">Zephir Website</div>
      <div class="cite-card__description">
        Zephir is an open source, high-level/domain specific language designed to ease the…
      </div>

    <div class="cite-card__site">Zephir Website</div>
  </a>
</aside>

<p>最後に、いつぞやのPHPカンファレンスで見た尊敬するRasmus Lerdorfのインタビュー記事でも載せておこうかな〜</p>
<aside class="cite-card">
    <img
      class="cite-card__image"
      src="https://gihyo.jp/assets/images/ICON/2015/1458_rasmus-interview.jpg"
      alt=""
      loading="lazy"
    >

  <a href="http://gihyo.jp/news/report/2015/12/1401" target="_blank" rel="noopener noreferrer">
    <div class="cite-card__title">PHPの生みの親、ラスマス・ラードフ氏インタビュー</div>
      <div class="cite-card__description">
        2015年12月に無事公開されたPHP7。その公開に先立ってPHPの生みの親であるラスマス・ラードフ氏に話を伺う機会がありました。がラスマス氏の思想がよく分かる話題が多く、可能な限…
      </div>

    <div class="cite-card__site">gihyo.jp</div>
  </a>
</aside>

]]></content></item></channel></rss>