search
LoginSignup
46
Help us understand the problem. What are the problem?

More than 5 years have passed since last update.

posted at

updated at

PHPでLINQ

Ginq / PHPLinq

PHPでLINQを再現するライブラリ、GINQを試してみます。

そもそもLINQって何よ。
http://ja.wikipedia.org/wiki/%E7%B5%B1%E5%90%88%E8%A8%80%E8%AA%9E%E3%82%AF%E3%82%A8%E3%83%AA

データ集合に対して標準化された方法でデータを問い合わせることを可能にする

.NET Framework に汎用クエリ機能が追加され、リレーショナル データや XML データだけでなく、あらゆる情報ソースにクエリ機能が適用されます。

何のこっちゃ。
平たく言うと、配列やらオブジェクトやらその他諸々の集合に対してSQL(っぽいもの)でSELECTできちまうぜ、という代物らしい。
さっそく試してみましょう。

<?php
    // Ginq
    require_once('path/to/ginq/Ginq.php');

    $sample1 = ['John', 'Peter', 'Joe', 'Patrick', 'Donald', 'Eric', 'Joe'];

    // SELECT name FROM sample1 WHERE LENGTH(name) < 5
    $under5 = Ginq::from($sample1)
        ->where(function($name){return strlen($name) < 5;})
        ->toArray();

    // SELECT DISTINCT name FROM sample1 ORDER BY id DESC
    $reverse = Ginq::from($sample1)->reverse()->distinct()->toArray();

    // Employee PHPLinqのサンプルのコピペ
    class Employee {
        public $Id, $DepartmentId, $ManagerId, $Name, $Email, $Age;
        public function __construct($id = 0, $departmentId = 0, $managerId = 0, $name = '', $email = '', $age = '') {
            $this->Id               = $id;
            $this->DepartmentId     = $departmentId;
            $this->ManagerId        = $managerId;
            $this->Name             = $name;
            $this->Email            = $email;
            $this->Age              = $age;
        }
    }
    $employees = [
        new Employee(1, 1, 5, 'Maarten', 'maarten@example.com', 24),
        new Employee(2, 1, 5, 'Paul', 'paul@example.com', 30),
        new Employee(3, 2, 5, 'Bill', 'bill.a@example.com', 29),
        new Employee(4, 3, 5, 'Bill', 'bill.g@example.com', 28),
        new Employee(5, 2, 0, 'Xavier', 'xavier@example.com', 40)
    ];

    // SELECT Email, SUBSTR(Email, INSTR(Email,'@')+1) FROM employees WHERE LENGTH(Name) = 4 ORDER BY Age DESC LIMIT 2 OFFSET 1
    $result = Ginq::from($employees)
        ->where(function($employee){ return strlen($employee->Name) === 4; })
        ->orderByDesc(function($employee){ return $employee->Age; })
        ->drop(1)->take(2)
        ->select(function($employee){ return [
            'EmailAddress' => $employee->Email,
            'Domain' => substr($employee->Email, strpos($employee->Email, "@") + 1)
            ]; })
        ->toArray();

コメントで書かれているSQLとほぼ同じ処理を、メソッドチェーンでSQLっぽく書くことができるようになりました。
SQLそのものではありませんが、同じようなかんじで使えます。
いちいちarray_filter()してforeachで抽出して、といった面倒な処理を書かなくて済みます。

前回のPHPLinqとほぼ同じですが、fromがIteratorに対応しているため、ArrayObjectやSPLなんかも突っ込めます。
また大抵のメソッドがcallableを受け取れるので、文字列で書かなければいけないPHPLinqより楽で汎用性があります。

まあ、このスライド見ればGinqの機能はだいたいわかります。
今回は使ってませんが、集計とかJOINとか他にもたくさん機能があり、また遅延実行にも対応しててパフォーマンスもよさげ。
けっこう使い勝手の良さそうなライブラリです。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
46
Help us understand the problem. What are the problem?