Logo

Maarten Balliauw {blog}

ASP.NET, ASP.NET MVC, Azure, PHP, OpenXML, VSTS, ...

About the author

Maarten Balliauw is currently employed as .NET Technical Consultant at RealDolmen. His interests are mainly web applications developed in ASP.NET (C#) or PHP and the Windows Azure cloud platform.
More about me More about me
Send mail E-mail me


ASP.NET MVC Quickly Subscribe to my RSS feed Follow me on Twitter! View Maarten Balliauw's profile on LinkedIn
View Maarten Balliauw's MVP profile

Search

Latest Twitter

    Follow me on Twitter...

    My projects

    Disclaimer

    The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

    © Copyright Maarten Balliauw 2010

    LINQ for PHP (Language Integrated Query for PHP)

    Perhaps you have already heard of C# 3.5's "LINQ" component. LINQ, or Language Integrated Query, is a component inside the .NET framework which enables you to perform queries on a variety of data sources like arrays, XML, SQL server, ... These queries are defined using a syntax which is very similar to SQL.

    There is a problem with LINQ though... If you start using this, you don't want to access data sources differently anymore. Since I'm also a PHP developer, I thought of creating a similar concept for PHP. So here's the result of a few days coding:

    PHPLinq - LINQ for PHP - Language Integrated Query

    A basic example

    Let's say we have an array of strings and want to select only the strings whose length is < 5. The PHPLinq way of achieving this would be the following:

    // Create data source
    $names = array("John", "Peter", "Joe", "Patrick", "Donald", "Eric");

    $result = from('$name')->in($names)
                ->where('$name => strlen($name) < 5')
                ->select('$name');

    Feels familiar to SQL? Yes indeed! No more writing a loop over this array, checking the string's length, and adding it to a temporary variable.

    You may have noticed something strange... What's that $name => strlen($name) < 5 doing? This piece of code is compiled to an anonymous function or Lambda expression under the covers. This function accepts a parameter $name, and returns a boolean value based on the expression strlen($name) < 5.

    An advanced example

    There are lots of other examples available in the PHPLinq download, but here's an advanced one... Let's say we have an array of Employee objects. This array should be sorted by Employee name, then Employee age. We want only Employees whose name has a length of 4 characters. Next thing: we do not want an Employee instance in our result. Instead, the returning array should contain objects containing an e-mail address and a domain name.

    First of all, let's define our data source:

    class Employee {
        public $Name;
        public $Email;
        public $Age;

        public function __construct($name, $email, $age) {
            $this->Name     = $name;
            $this->Email     = $email;
            $this->Age        = $age;
        }
    }

    $employees = array(
        new Employee('Maarten', 'maarten@example.com', 24),
        new Employee('Paul', 'paul@example.com', 30),
        new Employee('Bill', 'bill.a@example.com', 29),
        new Employee('Bill', 'bill.g@example.com', 28),
        new Employee('Xavier', 'xavier@example.com', 40)
    );

    Now for the PHPLinq query:

    $result = from('$employee')->in($employees)
                ->where('$employee => strlen($employee->Name) == 4')
                ->orderBy('$employee => $employee->Name')
                ->thenByDescending('$employee => $employee->Age')
                ->select('new {
                        "EmailAddress" => $employee->Email,
                        "Domain" => substr($employee->Email, strpos($employee->Email, "@") + 1)
                      }'
    );

    Again, you may have noticed something strange... What's this new { } thing doing? Actually, this is converted to an anonymous type under the covers. new { "name" => "test" } is evaluated to an object containing the property "name" with a value of "test".

    This all sounds intuitive, interesting and very handy? Indeed! Now make sure you download a copy of PHPLinq today, try it, and provide the necessary feedback / feature requests on the CodePlex site.


    Categories: General | LINQ | PHP | Projects | Software

    Comments

    Cory Borrow United States | Reply

    Thursday, January 24, 2008 9:09 PM

    Cory Borrow

    Hey, this looks great. It should become very useful in many tasks. Thanks.

    Logan Buesching United States | Reply

    Monday, March 17, 2008 5:13 PM

    Logan Buesching

    Wow!  Very interesting stuff happening here.  I had used a little bit of LINQ late last year and really, really enjoyed it, and I'm really glad to see it on PHP.  I will have to use this and see how it works in my own applications.

    mark People's Republic of China | Reply

    Thursday, March 20, 2008 3:15 PM

    mark

    Let the var become database table, greate.

    smt Italy | Reply

    Wednesday, March 26, 2008 2:05 PM

    smt

    ...->select('new {
                        "EmailAddress" => $employee->Email,
                        "Domain" => substr($employee->Email, strpos($employee->Email, "@") + 1)
                      }');

    this is not much KISS in the style of PHP, let this return an array:
    ...->select('
                        "EmailAddress" => $employee->Email,
                        "Domain" => substr($employee->Email, strpos($employee->Email, "@") + 1)
                      ');

    great work, impatient to see it working with mysql!

    maartenba Belgium | Reply

    Wednesday, March 26, 2008 2:14 PM

    maartenba

    select(' array(....) '); should do the trick.

    MySQL will be one of the next things on the list, I want a full implementation on arrays first.

    Christian Hammers Germany | Reply

    Tuesday, April 01, 2008 1:02 PM

    Christian Hammers

    Some comments:
    1. Look at the 'PHP doctrine' Object-Relational-Mapper, they have already invented a similar syntax.
    2. Why not make a function that creates a temporary sqlite table and then use real SQL or the doctrine LINQ syntax on it. Would look almost the same but had more features
    3. The advantages in C# were (IIRC) that the query language was actually *part* of the programming language and thus variables and keywords were syntax checked at compile time. Here even functions like substr() and strpos() are parts of a string and cannot be checked. Don't know how to improve that without hacking the PHP parser but maybe you want to play around with SQL as part of PHP. Real SQL is IMHO easer to read that your chain
    of functions Smile

    maartenba | Reply

    Tuesday, April 01, 2008 1:14 PM

    maartenba

    I agree with comment number 3 Smile Unfortunately, I'm not that good at C and C++ to hack this into the PHP compiler. *sigh*

    Evgeniy Ukraine | Reply

    Tuesday, April 01, 2008 7:21 PM

    Evgeniy

    I think that some extended functionality can be added with Reflection, for example attributes reading like in C#.
    Reflection classes has getDocComment() method that can be used to retrieve comments....
    It's useful for DB entities...
    For example:
    /** [Table(Name="MyTable")] */
    class MyTable
    {
      /** [Column] */
        protected $id;
      /** [Column] */
        protected $mode;
    ...
    }

    maartenba Belgium | Reply

    Wednesday, April 02, 2008 7:53 AM

    maartenba

    That might be a good idea to extend PHPLinq further with LinqToDatabase or something. For now it's only LinqToObjects. But I like the idea of annotations in PHP!

    Mayuika bhatt India | Reply

    Tuesday, April 22, 2008 2:16 PM

    Mayuika bhatt

    Hi. its great. i want to have select and insert queries using LINQ in MySQL. If its extended it would be awesome. i m waiting for mysql+LINQ

    Ren United Kingdom | Reply

    Saturday, May 31, 2008 1:19 AM

    Ren


    With the operator overload extension can remove alot of the strings, and have actual objects representing the tables and columns.. like

      $q = new mcQuery();
      $q->from(
        $q->leftJoin($catalog->Persons,
                $catalog->Employees,
                $catalog->Persons->personId == $catalog->Employees->employeeId)
      )->where($catalog->Persons->name < 'Ren');
      $q->append($catalog->Persons->name . ' ' . $catalog->Persons->personId);

    johno Slovakia | Reply

    Friday, June 06, 2008 5:04 PM

    johno

    Well, I've created a library for PHP annotations by extending reflection classes. You might want to check it out first http://code.google.com/p/addendum/

    V.K People's Republic of China | Reply

    Thursday, June 19, 2008 12:41 PM

    V.K

    how can i get it?

    maartenba Belgium | Reply

    Monday, June 23, 2008 7:53 AM

    maartenba

    Check http://www.phplinq.net

    Roon United Kingdom | Reply

    Tuesday, October 14, 2008 6:24 PM

    Roon

    I have heard a lot about this, but have only just realised someone has created a PHP library for LINQ, gonna give this a good trying out after work today!

    Justin Canada | Reply

    Friday, November 28, 2008 1:58 PM

    Justin

    Any hints as to when we can expect LinqToDatabase???

    I like where this is going.

    maartenba Belgium | Reply

    Friday, November 28, 2008 2:33 PM

    maartenba

    Working on it, but pace is not fast due to full agenda...

    Jacob Straszynski Canada | Reply

    Saturday, August 01, 2009 9:48 AM

    Jacob Straszynski

    This is awesome. In fact, it's so awesome it should be a first-order concept in PHP. Your API is great, I just wish that there was a PECL implementation of it because it's one of those low level fundamental things you want to start using everywhere.

    There needs to be noise here!

    Add comment




      Country flag

    biuquote
    • Comment
    • Preview
    Loading