Are you happy with your logging solution? Would you help us out by taking a 30-second survey? Click here

linq

PHP implementation of LINQ 2 Objects

Subscribe to updates I use linq


Statistics on linq

Number of watchers on Github 72
Number of open issues 3
Average time to close an issue about 1 month
Main language PHP
Average time to merge a PR 7 days
Open pull requests 0+
Closed pull requests 4+
Last commit about 2 years ago
Repo Created over 6 years ago
Repo Last Updated over 1 year ago
Size 519 KB
Homepage http://fusonic.gi...
Organization / Authorfusonic
Latest Releasev2.0.4
Contributors5
Page Updated
Do you use linq? Leave a review!
View open issues (3)
View linq activity
View on github
Fresh, new opensource launches πŸš€πŸš€πŸš€
Trendy new open source projects in your inbox! View examples

Subscribe to our mailing list

Evaluating linq for your project? Score Explanation
Commits Score (?)
Issues & PR Score (?)

fusonic/linq

Build Status Total Downloads

fusonic/linq is a lightweight PHP library inspired by the LINQ 2 Objects extension methods in .NET.

For a full introduction read my blog-post: http://www.fusonic.net/en/blog/2013/08/14/fusonic-linq-write-less-do-more/

LINQ queries offer three main advantages over traditional foreach loops:

  • They are more concise and readable, especially when filtering multiple conditions.

  • They provide powerful filtering, ordering, and grouping capabilities with a minimum of application code.

  • In general, the more complex the operation you want to perform on the data, the more benefit you will realize by using LINQ instead of traditional iteration techniques.

Requirements

fusonic/linq is supported on PHP 5.5 and up.

Installation & Usage

The most flexible installation method is using Composer: Simply create a composer.json file in the root of your project:

{
    "require": {
        "fusonic/linq": "@dev"
    }
}

Install composer and run install command:

curl -s http://getcomposer.org/installer | php
php composer.phar install

Once installed, include vendor/autoload.php in your script to autoload fusonic/linq.

require 'vendor/autoload.php';
use Fusonic\Linq\Linq;

Linq::from([])->count();

Examples

Calculate the average file size of files in a directory:

$source = glob("files/*");
Linq::from($source)
  ->select(function($i) { return filesize($i); })
  ->average();

Find all files bigger than 1024 bytes and return the fileinfo object:

$source = glob("files/*");
Linq::from($source)
  ->where(function($i) { return filesize($i) > 1024; })
  ->select(function($i) { return pathinfo($i); });

Search for all users containing Max 1, Skip 5 items, Take 2 items and select the property ID of each user:

$result = Linq::from($users)
    ->where(function (User $u) { return strstr($u->surname, "Max 1");  })
    ->skip(5)
    ->take(2)
    ->select(function (User $u) { return $u->usrId; });

Flatten multiple sequences into one sequence:

$array1 = ["key" => "a", "data" => ["a1", "a2"]];
$array2 = ["key" => "b", "data" => ["b1", "b2"]];
$array3 = ["key" => "c", "data" => ["c1", "c2"]];

$allArrays = [$array1, $array2, $array3];

$result = Linq::from($allArrays)
    ->selectMany(function($x) { return $x["data"]; })
    ->toArray();

// $result is now: ["a1", "a2", "b1", "b2", "c1", "c2"];

Map sequence to array with key/value selectors:

$category1 = new stdClass(); $category1->key = 1; $category1->value = "Cars";
$category2 = new stdClass(); $category2->key = 2; $category2->value = "Ships";

$result = Linq::from([$category1, $category2])
    ->toArray(
        function($x) { return $x->key; }, // key-selector
        function($x) { return $x->value; } // value-selector
    );

// $result is now: [1 => "Cars", 2 => "Ships"];

The aggregate method makes it simple to perform a calculation over a sequence of values:

$numbers = Linq::from([1,2,3,4]);
$sum = $numbers->aggregate(function($a, $b) { return $a + $b; });
// echo $sum; // output: 10 (1+2+3+4)

$chars = Linq::from(["a", "b", "c"]);
$csv = $chars->aggregate(function($a, $b) { return $a . "," . $b; });
// echo $csv; // output: "a,b,c"

$chars = Linq::from(["a", "b", "c"]);
$csv = $chars->aggregate(function($a, $b) { return $a . "," . $b; }, "seed");
// echo $csv; // output: "seed,a,b,c"

The chunk method makes it simple to split a sequence into chunks of a given size:

$chunks = Linq::from(["a","b","c","d","e"])->chunk(2);
$i = 0;
foreach($chunk in $chunks) {
  $i++;
  echo "Row $i <br>";
  foreach($char in $chunk) {
    echo $char . "|";
  }
}
// Result:
// Row 1
// a|b
// Row 2
// c|d
// Row 3
// e|

List of methods provided by fusonic/linq:

aggregate($func, $seed = null) // Applies an accumulator function over a sequence.
all($func) // Determines wheter all elements satisfy a condition.
any($func) // Determines wheter any element satisfies a condition.
average($func = null) // Computes the average of all numeric values.
concat($second) // Concatenates 2 sequences
contains($value) // Determines whether a sequence contains a specified element.
count() // Counts the elements of the sequence.
chunk($chunksize) // Splits the sequence in chunks according to $chunksize.
except($second) // Returns all items except the ones of the given sequence.
distinct($func = null) // Returns all distinct items of a sequence using the optional selector.
each($func) // Performs the specified action on each element of the sequence.
elementAt($index) // Returns the element at a specified index or throws an exception.
elementAtOrNull($index) // Returns the element at a specified index or returns null
first($func = null) // Returns the first element that satisfies a specified condition or throws an exception.
firstOrNull($func = null) // Returns the first element, or NULL if the sequence contains no elements.
groupBy($keySelector) // Groups the object according to the $keySelector generated key.
intersect($second) // Intersects the Linq sequence with second Iterable sequence.
last($func = null) // Returns the last element that satisfies a specified condition or throws an exception.
lastOrNull($func = null) // Returns the last element that satisfies a condition or NULL if no such element is found.
max($func = null) //  Returns the maximum item value according to $func.
min($func = null) //  Returns the minimum item value according to $func
orderBy($func) // Sorts the elements in ascending order according to a key provided by $func.
orderByDescending($func) // Sorts the elements in descending order according to a key provided by $func.
select($func) // Projects each element into a new form by invoking the selector function.
selectMany($func) // Projects each element of a sequence to a new Linq and flattens the resulting sequences into one sequence. 
single($func = null) // Returns the only element that satisfies a specified condition or throws an exception.
singleOrDefault($func = null) // Returns the only element that satisfies a specified condition or returns Null.
skip($count) // Bypasses a specified number of elements and then returns the remaining elements.
sum($func = null) // Gets the sum of all items or by invoking a transform function on each item to get a numeric value.
take($count) // Returns a specified number of contiguous elements from the start of a sequence.
toArray($keySelector=null, $valueSelector=null) // Creates an Array from this Linq object with an optional key selector.
where($func) // Filters the Linq object according to func return result.

Simple, Consistent and Predictable

One important design goal was the principle of the least surprise. As PHP is a fully dynamic language with nearly no type-safety, it is common to shoot yourself into the foot because of accidentally mixing up incompatible types.

We protect you from these programing errors by asserting that every callback functions you supply to the library must return a correctly typed value. In addition, every supported aggregate function will throw an exception if you are accidentally mixing up incompatible types.

This means that we made this library totally predictable in what it does, and verified that every function has its defined exceptions which are thrown when certain operations fail, or if certain types are not correct.

/* Throws an UnexpectedValueException if the 
provided callback function does not return a boolean */
Linq::from(["1", "1"])
->where(function($x) { return "NOT A BOOLEAN"; });

/* Throws an UnexpectedValueException if one of the values
is not convertible to a numeric value:*/
Linq::from([1, 2, "Not a numeric value"])
->sum();

Running tests

./vendor/bin/phpunit tests/
linq questions on Stackoverflow (View All Questions)
  • Error while re-using an expression using PredicateBuilder in LINQ
  • Linq Query not returning previous 6 months
  • Writing XML with Linq: Token EndDocument in state Document would result in an invalid XML document
  • Parsing XML with values containing angle brackets, using Linq
  • C# linq for loop inside the add method
  • Mapping models with Linq
  • LINQ to SQL Debug Visualizer visual studio 2013
  • Windows service C# Linq and EF4 ArgumentException at ChangeConnectionString()
  • How to Compare strings in Linq Query
  • β€œSystem.ArgumentException: Value does not fall within the expected range” when executing LINQ to sharepoint query
  • Compare time only in linq to sql with time rang
  • Can I use LINQ when the data source can change?
  • Linq: the best overloaded match has some invalid arguments
  • C# Linq query flattening multi-level classes
  • C# - How to achieve multiple matching from a single string by using Linq and Regex?
  • How to populate a Class with Dictionary using LINQ
  • How to Convert complicated SQL query to LINQ
  • Use LINQ aggregator dynamically
  • Linq select a range between two strings, such as Col thru Io
  • linq how to check all rows are null
  • How to show image in GridView form database linq
  • Using LINQ with MySQL database that can change in production
  • Linq on DateTime Collections Best Performance
  • LINQ Join 2 Datatables and With SUM AND GROUP BY
  • The specified type member is not supported in LINQ to Entities. entity members, and entity navigation
  • Linq to SQL - Exact Relational Division
  • Join List<> with List of <List<> using LINQ
  • Stored Procedure slower than LINQ query?
  • How can find specific HashSet elements with linq
  • Lambda Linq WITH NESTED STRING
linq list of languages used
linq latest release notes

30: Removed the TestBase base class for unit tests.

Bugfix release for the 2.x series.

Bugs fixed in this release:

https://github.com/fusonic/linq/pull/28 Fixed issue with InvalidArgumentException when a string is passed as chunk-size

Bugfix release for the 2.x series.

Bugs fixed in this release:

24 Use PHP 5.4 features

25 Prevent array type being picked up as missing class

27 Fix problem using IteratorAggregates with skip and take

Other projects in PHP