Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
46
Help us understand the problem. What is going on with this article?
@rana_kualu

PHPでLINQ

More than 5 years have passed since last update.

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とか他にもたくさん機能があり、また遅延実行にも対応しててパフォーマンスもよさげ。
けっこう使い勝手の良さそうなライブラリです。

46
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
rana_kualu
不労所得で生きたい。

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
46
Help us understand the problem. What is going on with this article?