Is there something in PHP equivalent to LINQ in C#?
Try YaLinqo. It is the best LINQ for PHP.
Here is a comparison table:
(YaLinqo developer here.)
Currently, there are three major implementations of LINQ in PHP:
YaLinqo — the most minimalistic library architecture-wise (4 classes), but the most featureful, the most performant, with the best documentation and the only one supporting "string lambdas".
Ginq — a library of average size (70 classes), on par with YaLinqo in the number of functions, around 1.5–3x times slower, contains custom collections, iterators and comparers, documentation contains argument types at best.
Pinq — a huge library (500 classes), supports parsing PHP and transforming into SQL and everything else, much slower than the rest, has a pretty website, but its documentation is average and functionality is lacking.
Other libraries aren't worth being mentioned (um, okay, LINQ for PHP, Phinq, PHPLinq and Plinq). They're barely tested, evaluations in them aren't lazy, they rely on weird concepts alien to both PHP and .NET developers. PHPLinq is the only one which actually supports databases, but it's more like DAL for generating SQL with a fixed call order rather than LINQ.
If you ask me what library to choose, I'd just say to use YaLinqo if you need to work with arrays and objects and any ORM library (not LINQ) when you need to work with databases. But I'll try to explain why.
Performance
YaLinqo is by far the fastest of the libraries. It's designed to be fast: it relies only on generators (which produce the fastest iterators); it uses only arrays (no custom collections implemented as wrappers around arrays). Its evolution is getting rid of slow and outdated features: removing custom collections, removing explicit iterators; and worsening code quality if it improves performance: choosing between multiple sort functions instead of using one generic solution, copy-pasting code to reduce the number of function calls.
Ginq and Pinq took another approach, they use explicit iterator classes. It bites a big chunk out of performance, but allows using iterators separately from fluent method syntax.
Furthermore, they both have performance traps. When you use property accessors syntax in Ginq, your code becomes 5 times slower. There're also surprises awaiting you when you try using arrays as keys. When you use joining in Pinq, your code becomes hundreds or thousands times slower (I'm not joking, see links below) Performace of joining in Pinq was fixed after my bug report.
With YaLinqo, it's simpler: either it doesn't work (like arrays in keys), or it works with expected performance. Version 1 did have some hacks to make it possible, like in original LINQ, but the current version doesn't. It may require some adjustments: for example, instead of using an equality comparer, you'll need to produce keys which are equal in the same cases.
See articles: LINQ for PHP comparison: YaLinqo, Ginq, Pinq on CodeProject, LINQ for PHP: speed matters on Habrahabr (Russian). They cover YaLinqoPerf, git repository with performance tests comparing raw PHP, YaLinqo, Ginq and Pinq.
Features
The number of LINQ methods in YaLinqo and Ginq, as well as their functionaility, are pretty close. I'd say there's no clear winner, as both libraries provide methods the other one doesn't have. They are mostly extra methods unavailable in the original LINQ, so I wouldn't worry about it too much.
Pinq looks like a deserted town. Methods are barebones and are often barely usable. While writing peformance tests, I often had to resort to custom more complex solutions for Pinq, while code for YaLinqo and Pinq usually differed only in method names (different naming conventions: "desc" vs. "descending" and things like that).
On the other hand, Pinq is the only one which supports parsing PHP and generating SQL from it. Unfortunately, the only query provider is for MySQL and its state is a "demonstration". So, while Pinq has this unique feature, it can't be used yet, unfortunately.
If you want LINQ to databases to become a reality, I guess you have no choice but to start on working on a query provider for Pinq. It's a very complex task, and I doubt one developer is able to produce high-quality query providers for all databases alone.
What Ginq has that YaLinqo doesn't is more advanced architecture. Where Set
and Dictionary
classes are used in Ginq, you'll see arrays and only arrays in YaLinqo. Where Comparer
and EqualityComparer
are used in Ginq, you'll see closures (or no equivalent) in YaLinqo. At the core, it's a design decision — whether library should use concepts natural for programmers in this language or for programmers used to the library in other languages. The libraries just made a choice.
It should be noted that more complex architecture doesn't equal a good implementation. Ginq uses public function hash($v) { return sha1(serialize($v)); }
for calculating key hashes in "sets", for example.
Documentation
YaLinqo stands out with a good reference documentation in PHPDoc and online (generated from PHPDoc). It's mostly documentation of LINQ in .NET from MSDN adapted to PHP. If you know what MSDN is, you know its quality.
Ginq's documentation is almost non-existent, it usually contains just argument type hints.
Pinq's documentation is relatively good (every major method has a sentence or two explaining what it does), but it's no match for YaLinqo's documentation.
Both Ginq and Pinq have good introductory artcicles on the web which explain concepts to new developers. YaLinqo doesn't have any introductory documentation besides a crazy example in ReadMe which doesn't explain anything.
Pinq has a pretty website too, the only one of the three libraries.
Everything else
All three libraries have good test coverage, Composer integration, permissive open-source licenses, and other properties of libararies which are ready to be used in production.
For those who care about ancient PHP versions, YaLinqo 1.x requires PHP 5.3, YaLinqo 2.x requires PHP 5.5, Ginq requires PHP 5.3, Pinq requires PHP 5.4.
P.S. If you have any additions, or think I'm biased, please comment. Comments are what I miss after writing so much text. :)
There is PHPLinq - LINQ for PHP.