Logo

Maarten Balliauw {blog}

ASP.NET, ASP.NET MVC, Windows Azure, PHP, ...

About the author

Maarten Balliauw is currently employed as a Technical Evangelist at JetBrains. 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 Pro NuGet Subscribe to my RSS feed Follow me on Twitter! View Maarten Balliauw's profile on LinkedIn
Maarten Balliauw - MVP - Most Valuable Professional
Maarten Balliauw - ASPInsider

Search

Archive

Disclaimer

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

© Copyright Maarten Balliauw 2013


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 (19) -

Cory Borrow United States |

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 |

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 |

Thursday, March 20, 2008 3:15 PM

mark

Let the var become database table, greate.

smt Italy |

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 |

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 |

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 |

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 |

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 |

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 |

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 |

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 |

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 |

Thursday, June 19, 2008 12:41 PM

V.K

how can i get it?

maartenba Belgium |

Monday, June 23, 2008 7:53 AM

maartenba

Check http://www.phplinq.net

Roon United Kingdom |

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 |

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 |

Friday, November 28, 2008 2:33 PM

maartenba

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

Jacob Straszynski Canada |

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!

Sorgfelt United States |

Thursday, April 07, 2011 10:23 PM

Sorgfelt

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.

Comments are closed