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:

[code:c#]

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

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

[/code]

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:

[code:c#]

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', '[email protected]', 24),
    new Employee('Paul', '[email protected]', 30),
    new Employee('Bill', '[email protected]', 29),
    new Employee('Bill', '[email protected]', 28),
    new Employee('Xavier', '[email protected]', 40)
);

[/code]

Now for the PHPLinq query:

[code:c#]

$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)
                  }');

[/code]

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.

This is an imported post. It was imported from my old blog using an automated tool and may contain formatting errors and/or broken images.

Leave a Comment

avatar

21 responses

  1. Avatar for Cory Borrow
    Cory Borrow January 25th, 2008

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

  2. Avatar for ljbuesch
    ljbuesch March 17th, 2008

    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.

  3. Avatar for mark
    mark March 20th, 2008

    Let the var become database table, greate.

  4. Avatar for smt
    smt March 26th, 2008

    [quote]...->select('new {
    "EmailAddress" => $employee->Email,
    "Domain" => substr($employee->Email, strpos($employee->Email, "@") + 1)
    }');
    [/quote]
    this is not much KISS in the style of PHP, let this return an array:
    [quote]...->select('
    "EmailAddress" => $employee->Email,
    "Domain" => substr($employee->Email, strpos($employee->Email, "@") + 1)
    ');
    [/quote]
    great work, impatient to see it working with mysql!

  5. Avatar for maartenba
    maartenba March 26th, 2008

    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.

  6. Avatar for Christian Hammers
    Christian Hammers April 1st, 2008

    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 :)

  7. Avatar for maartenba
    maartenba April 1st, 2008

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

  8. Avatar for Evgeniy
    Evgeniy April 2nd, 2008

    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;
    ...
    }

  9. Avatar for maartenba
    maartenba April 2nd, 2008

    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!

  10. Avatar for Mayuika bhatt
    Mayuika bhatt April 22nd, 2008

    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

  11. Avatar for Ren
    Ren May 31st, 2008

    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);

  12. Avatar for johno
    johno June 6th, 2008

    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/ad...

  13. Avatar for V.K
    V.K June 19th, 2008

    how can i get it?

  14. Avatar for maartenba
    maartenba June 23rd, 2008
  15. Avatar for Roon
    Roon October 15th, 2008

    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!

  16. Avatar for Justin
    Justin November 28th, 2008

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

    I like where this is going.

  17. Avatar for maartenba
    maartenba November 28th, 2008

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

  18. Avatar for Jacob Straszynski
    Jacob Straszynski August 1st, 2009

    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!

  19. Avatar for Sorgfelt
    Sorgfelt April 8th, 2011

    There is a problem with PHPLinq that many have noticed: It is not really Language INtegrated, but, instead uses evaluated strings. A better implementation of the LINQ idea that really is Language INtegrated has been developed. See plinq.codeplex.com or linqforphp.codeplex.com .
    This needs to be spread, rather than everyone jumping on the first, but badly designed, PHPLinq bandwagon.

  20. Avatar for Guest
    Guest August 28th, 2013

    awesome blog

  21. Avatar for pay for my essay
    pay for my essay May 20th, 2016

    It's really wonderful that this kind of information was being shared in order for someone to improve their knowledge regarding on the use of this kind of programming language that would totally be a perfect fit for their success.