{"id":22546496,"url":"https://github.com/penobit/linq","last_synced_at":"2025-09-11T09:39:03.603Z","repository":{"id":57037693,"uuid":"384690019","full_name":"penobit/linq","owner":"penobit","description":"Language-Integrated Query (LINQ) for PHP language","archived":false,"fork":false,"pushed_at":"2021-08-23T00:59:07.000Z","size":27,"stargazers_count":2,"open_issues_count":0,"forks_count":2,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-06-12T20:05:26.679Z","etag":null,"topics":["array","json","linq","php"],"latest_commit_sha":null,"homepage":"https://penobit.com","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/penobit.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-07-10T12:13:27.000Z","updated_at":"2022-12-16T22:04:24.000Z","dependencies_parsed_at":"2022-08-23T21:00:16.973Z","dependency_job_id":null,"html_url":"https://github.com/penobit/linq","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"purl":"pkg:github/penobit/linq","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/penobit%2Flinq","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/penobit%2Flinq/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/penobit%2Flinq/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/penobit%2Flinq/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/penobit","download_url":"https://codeload.github.com/penobit/linq/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/penobit%2Flinq/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":259521511,"owners_count":22870448,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["array","json","linq","php"],"created_at":"2024-12-07T15:08:00.805Z","updated_at":"2025-06-12T20:05:26.895Z","avatar_url":"https://github.com/penobit.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# LinQ\n\n## Language-Integrated Query (**LINQ**) for **PHP** language\n\n## Installation\n\n```shell\ncomposer require penobit/linq\n```\n\n## Usage\n\nYou can start using this package right away by importing your JSON data from a file:\n\n```php\nuse Penobit\\Linq\\Linq;\n$linq = new Linq($data);\n```\n\nImporting data from a PHP array or json string:\n\n```php\n$linq-\u003ecollect(['id'=\u003e1, 'name'=\u003e'Penobit']);\n```\n\nOr using short handed function\n\n```php\nlinq($data);\n```\n\n## Example JSON Data\n\nLet's have a quick example:\n\n```json\n//data.json\n{\n   \"name\": \"Penobit Linq for PHP\",\n   \"description\": \"This is an example for php linq by Penobit.com\",\n   \"vendor\":{\n      \"name\": \"Penobit\",\n      \"email\": \"info@penobit.com\",\n      \"website\":\"www.penobit.com\"\n   },\n   \"users\":[\n      {\"id\":1, \"name\":\"R8\", \"location\": \"Tehran\"},\n      {\"id\":2, \"name\":\"Amin Goodarzi\", \"location\": \"Ohio\"},\n      {\"id\":3, \"name\":\"Amir Jahangiri\", \"location\": \"Louisiana\"},\n      {\"id\":4, \"name\":\"Jack Smith\", \"location\": \"New York\"},\n      {\"id\":5, \"name\":\"John Doe\", \"location\": \"Manchester\"},\n      {\"id\":6, \"name\":\"Sara Savari\", \"location\": \"Tehran\", \"visits\": [\n         {\"name\": \"Home page\", \"year\": 2020},\n         {\"name\": \"Client area\", \"year\": 2021},\n         {\"name\": \"Admin panel\", \"year\": 2019}\n      ]}\n   ],\n   \"products\": [\n      {\"id\":1, \"userID\": 2, \"city\": \"TEH\", \"name\":\"iPhone\", \"cat\":1, \"price\": 80000},\n      {\"id\":2, \"userID\": 2, \"city\": null, \"name\":\"macbook pro\", \"cat\": 2, \"price\": 150000},\n      {\"id\":3, \"userID\": 2, \"city\": \"NY\", \"name\":\"iWatch\", \"cat\": 1, \"price\": 12000},\n      {\"id\":4, \"userID\": 1, \"city\": null, \"name\":\"iMac\", \"cat\":1, \"price\": 15000},\n      {\"id\":5, \"userID\": 1, \"city\": \"TEH\", \"name\":\"macbook air\", \"cat\": 2, \"price\": 110000},\n      {\"id\":6, \"userID\": 2, \"city\": null, \"name\":\"macbook air 1\", \"cat\": 2, \"price\": 81000}\n   ]\n}\n```\n\n```php\nuse Penobit\\JsonQ\\Linq;\n\n$q = new Linq($data);\n$res = $q-\u003efrom('products')\n    -\u003ewhere('cat', '=', 2)\n    -\u003eget('name', 'price');\n\n// or you could use $q-\u003eselect('name', 'price') or $q-\u003efetch('name', 'price')  instead of getch\n\nvar_dump($res-\u003etoArray());\n\n//This will print\n/*\narray:3 [▼\n  1 =\u003e {#7 ▼\n    +\"name\": \"macbook pro\"\n    +\"price\": 150000\n  }\n  4 =\u003e {#8 ▼\n    +\"name\": \"macbook air\"\n    +\"price\": 110000\n  }\n  5 =\u003e {#9 ▼\n    +\"name\": \"macbook air 1\"\n    +\"price\": 81000\n  }\n]\n*/\n```\n\nLet's say we want to get the Summation of _price_ of the Queried result. We can do it easily by calling the **sum()** method instead of **get()**:\n\n```php\n$result = $linq-\u003efrom('products')\n        -\u003ewhere('cat', '=', 2)\n        -\u003esum('price');\n\nvar_dump($result);\n\n//It will print:\n/*\n365000\n*/\n```\n\nThat was easy, wasn't it?\n\n## API\n\n\u003eHere is the list of available methods for querying.\n\nFollowing API examples are shown based on the sample JSON data given [here](#example-json-data)\n\n**List of API:**\n\n- [LinQ](#linq)\n  - [Language-Integrated Query (**LINQ**) for **PHP** language](#language-integrated-query-linq-for-php-language)\n  - [Installation](#installation)\n  - [Usage](#usage)\n  - [Example JSON Data](#example-json-data)\n  - [API](#api)\n    - [`fetch()`](#fetch)\n    - [`find(path)`](#findpath)\n    - [`from(path)`](#frompath)\n    - [`at(path)`](#atpath)\n    - [`where(key, condition, val)`](#wherekey-condition-val)\n    - [`where(key, op, val)`](#wherekey-op-val)\n    - [`callableWhere(fn)`](#callablewherefn)\n    - [`orCallableWhere(fn)`](#orcallablewherefn)\n    - [`orWhere(key, op, val)`](#orwherekey-op-val)\n    - [`whereIn(key, val)`](#whereinkey-val)\n    - [`whereNotIn(key, val)`](#wherenotinkey-val)\n    - [`whereNull(key)`](#wherenullkey)\n    - [`whereNotNull(key)`](#wherenotnullkey)\n    - [`whereStartsWith(key, val)`](#wherestartswithkey-val)\n    - [`whereEndsWith(key, val)`](#whereendswithkey-val)\n    - [`whereContains(key, val)`](#wherecontainskey-val)\n    - [`sum(column)`](#sumcolumn)\n    - [`count()`](#count)\n    - [`size()`](#size)\n    - [`max(column)`](#maxcolumn)\n    - [`min(column)`](#mincolumn)\n    - [`avg(column)`](#avgcolumn)\n    - [`first()`](#first)\n    - [`last()`](#last)\n    - [`nth(index)`](#nthindex)\n    - [`exists()`](#exists)\n    - [`groupBy(column)`](#groupbycolumn)\n    - [`sort(order)`](#sortorder)\n    - [`sortBy(column, order)`](#sortbycolumn-order)\n    - [`reset(data)`](#resetdata)\n    - [`copy()`](#copy)\n  - [Example Files](#example-files)\n\n### `fetch()`\n\nThis method will execute queries and will return the resulted data. You need to call it finally after using some query methods. Details can be found in other API examples like `get()`.\n\n### `find(path)`\n\n- `path` -- the path hierarchy of the data you want to find.\n\nYou don't need to call `fetch()` method after this. Because this method will fetch and return the data by itself.\n\n**caveat:** You can't chain further query methods after it. If you need that, you should use `at()` or `from()` method.\n\n**example:**\n\nLet's say you want to get the value of _'cities'_ property of your Json Data. You can do it like this:\n\n```php\n$q = new Linq($data);\necho $q-\u003efind('vendor.name');\n```\n\nIf you want to traverse to more deep in hierarchy, you can do it like:\n\n```php\n$q = new Linq($data);\necho $q-\u003efind('vendor.name');\n```\n\n\u003c!-- See a detail example [here](examples/find.js). --\u003e\n\n### `from(path)`\n\n- `path` (optional) -- the path hierarchy of the data you want to start query from.\n\nBy default, query would be started from the root of the JSON Data you've given. If you want to first move to a nested path hierarchy of the data from where you want to start your query, you would use this method. Skipping the `path` parameter or giving **'.'** as parameter will also start query from the root Data.\n\nDifference between this method and `find()` is that, `find()` method will return the data from the given path hierarchy. On the other hand, this method will return the Object instance, so that you can further chain query methods after it.\n\n**example:**\n\nLet's say you want to start query over the values of _'vendor.name'_ property of your JSON Data. You can do it like this:\n\n```php\n$q = new Linq($data);\necho $q-\u003efrom('vendor.name')-\u003eget();\n```\n\nIf you want to traverse to more deep in hierarchy, you can do it like:\n\n```php\n$q = new Linq($data);\necho $q-\u003efrom('users.5.visits')-\u003eget();\n```\n\n\u003c!-- See a detail example [here](examples/from.php). --\u003e\n\n### `at(path)`\n\nThis is an alias method of `from()` and will behave exactly like that.\n \u003c!-- See example [here](examples/from.php). --\u003e\n\n### `where(key, condition, val)`\n\n- `key` -- the property name of the data. Or you can pass a Function here to group multiple query inside it. See details in [example](examples/where.js)\n- `val` -- value to be matched with. It can be a _int_, _string_, _bool_ or even _Function_ - depending on the `op`.\n- `op` -- operand to be used for matching. The following operands are available to use:\n\n- `=` : For weak equality matching\n- `eq` : Same as `=`\n- `!=` : For weak not equality matching\n- `neq` : Same as `!=`\n- `==` : For strict equality matching\n- `seq` : Same as `==`\n- `!==` : For strict not equality matching\n- `sneq` : Same as `!==`\n- `\u003e` : Check if value of given **key** in data is Greater than **val**\n- `gt` : Same as `\u003e`\n- `\u003c` : Check if value of given **key** in data is Less than **val**\n- `lt` : Same as `\u003c`\n- `\u003e=` : Check if value of given **key** in data is Greater than or Equal of **val**\n- `gte` : Same as `\u003e=`\n- `\u003c=` : Check if value of given **key** in data is Less than or Equal of **val**\n- `lte` : Same as `\u003c=`\n- `null` : Check if the value of given **key** in data is **null** (`val` parameter in `where()` can be omitted for this `op`)\n- `notnull` : Check if the value of given **key** in data is **not null** (`val` parameter in `where()` can be omitted for this `op`)\n- `in` : Check if the value of given **key** in data is exists in given **val**. **val** should be a plain _Array_.\n- `notin` : Check if the value of given **key** in data is not exists in given **val**. **val** should be a plain _Array_.\n- `startswith` : Check if the value of given **key** in data starts with (has a prefix of) the given **val**. This would only works for _String_ type data.\n- `endswith` : Check if the value of given **key** in data ends with (has a suffix of) the given **val**. This would only works for _String_ type data.\n- `contains` : Check if the value of given **key** in data has a substring of given **val**. This would only works for _String_ type data.\n- `match` : Check if the value of given **key** in data has a Regular Expression match with the given **val**. The `val` parameter should be a **RegExp** for this `op`.\n- `macro` : It would try to match the value of given **key** in data executing the given `val`. The `val` parameter should be a **Function** for this `op`. This function should have a matching logic inside it and return **true** or **false** based on that.\n\n**example:**\n\n### `where(key, op, val)`\n\nLet's say you want to find the _'users'_ who has _`id`_ of `1`. You can do it like this:\n\n```php\n$q = new Linq($data);\n$res = $q-\u003efrom('users')-\u003ewhere('id', '=', 1)-\u003eget();\n// Or\n$res = $q-\u003efrom('users')-\u003ewhere('id', 1)-\u003eget();\n```\n\nYou can add multiple _where_ conditions. It'll give the result by AND-ing between these multiple where conditions.\n\n```php\n$q = new Linq($data);\n$res = $q-\u003efrom('users')\n    -\u003ewhere('id', '=', 1)\n    -\u003ewhere('location', '=', 'Tehran')\n    -\u003eget();\n```\n\n\u003c!-- See a detail example [here](examples/where.php). --\u003e\n\n### `callableWhere(fn)`\n\nParameter of `callableWhere()` is callable function that should return a `bool` (true/false)\n\n```php\n$q = new Linq($data);\n$res = $q-\u003efrom('users')\n    -\u003ecallableWhere(function($item) {\n        return $item['price'] \u003e 3000;\n    })\n    -\u003etoArray();\n```\n\n### `orCallableWhere(fn)`\n\nParameter and behaviour of `orCallableWhere()` is the same as `callableWhere()`\n\n```php\n$res = $q-\u003efrom('users')\n    -\u003ewhere('id', 1)\n    -\u003ecallableWhere(function($item) {\n        return $item['location'] == 'Tehran' \u0026\u0026  substr($item['name'], 0, 3) == 'mac';\n    })\n    -\u003eorCallableWhere(function($item) {\n        return $item['price'] \u003e 3000;\n    })\n    -\u003etoArray();\n```\n\n### `orWhere(key, op, val)`\n\nParameters of `orWhere()` are the same as `where()`. The only difference between `where()` and `orWhere()` is: condition given by the `orWhere()` method will OR-ed the result with other conditions.\n\nFor example, if you want to find the users with _id_ of `1` or `2`, you can do it like this:\n\n```php\n$q = new Linq($data);\n$res = $q-\u003efrom('users')\n    -\u003ewhere('id', '=', 1)\n    -\u003eorWhere('id', '=', 2)\n    -\u003eget();\n// Or\n$res = $q-\u003efrom('users')\n    -\u003ewhere('id', 1)\n    -\u003eorWhere('id', 2)\n    -\u003eget();\n```\n\n\u003c!-- See detail example [here](examples/or-where.php). --\u003e\n\n### `whereIn(key, val)`\n\n- `key` -- the property name of the data\n- `val` -- it should be an **Array**\n\nThis method will behave like `where(key, 'in', val)` method call.\n\n### `whereNotIn(key, val)`\n\n- `key` -- the property name of the data\n- `val` -- it should be an **Array**\n\nThis method will behave like `where(key, 'notin', val)` method call.\n\n### `whereNull(key)`\n\n- `key` -- the property name of the data\n\nThis method will behave like `where(key, 'null')` or `where(key, '=', null)` method call.\n\n### `whereNotNull(key)`\n\n- `key` -- the property name of the data\n\nThis method will behave like `where(key, 'notnull')` or `where(key, '!=', null)` method call.\n\n### `whereStartsWith(key, val)`\n\n- `key` -- the property name of the data\n- `val` -- it should be a String\n\nThis method will behave like `where(key, 'startswith', val)` method call.\n\n### `whereEndsWith(key, val)`\n\n- `key` -- the property name of the data\n- `val` -- it should be a String\n\nThis method will behave like `where(key, 'endswith', val)` method call.\n\n### `whereContains(key, val)`\n\n- `key` -- the property name of the data\n- `val` -- it should be a String\n\nThis method will behave like `where(key, 'contains', val)` method call.\n\n### `sum(column)`\n\n- `column` -- the property name of the data\n\n**example:**\n\nLet's say you want to find the sum of the _'price'_ of the _'products'_. You can do it like this:\n\n```php\n$q = new Linq($data);\n$res = $q-\u003efrom('products')\n    -\u003ewhere('cat', '=', 1)\n    -\u003esum('price');\n```\n\nIf the data you are aggregating is plain array, you don't need to pass the 'column' parameter.\n\u003c!-- See detail example [here](examples/sum.php) --\u003e\n\n### `count()`\n\nIt will return the number of elements in the collection.\n\n**example:**\n\nLet's say you want to find how many elements are in the _'products'_ property. You can do it like:\n\n```php\n$q = new Linq($data);\n$res = $q-\u003efrom('products')\n    -\u003ewhere('cat', '=', 1)\n    -\u003ecount();\n```\n\nSee detail example [here](examples/count.php).\n\n### `size()`\n\nThis is an alias method of `count()`.\n\n### `max(column)`\n\n- `column` -- the property name of the data\n\n**example:**\n\nLet's say you want to find the maximum of the _'price'_ of the _'products'_. You can do it like this:\n\n```php\n$q = new Linq($data);\n$res = $q-\u003efrom('products')\n    -\u003ewhere('cat', '=', 1)\n    -\u003emax('price);\n```\n\nIf the data you are querying is plain array, you don't need to pass the 'column' parameter.\n\u003c!-- See detail example [here](examples/max.php) --\u003e\n\n### `min(column)`\n\n- `column` -- the property name of the data\n\n**example:**\n\nLet's say you want to find the minimum of the _'price'_ of the _'products'_. You can do it like this:\n\n```php\n$q = new Linq($data);\n$res = $q-\u003efrom('products')\n    -\u003ewhere('cat', '=', 1)\n    -\u003emin('price');\n```\n\nIf the data you are querying is plain array, you don't need to pass the 'property' parameter.\n\u003c!-- See detail example [here](examples/min.php) --\u003e\n\n### `avg(column)`\n\n- `column` -- the property name of the data\n\n**example:**\n\nLet's say you want to find the average of the _'price'_ of the _'products'_. You can do it like this:\n\n```php\n$q = new Linq($data);\n$res = $q-\u003efrom('products')\n    -\u003ewhere('cat', '=', 1)\n    -\u003eavg('price');\n```\n\nIf the data you are querying is plain array, you don't need to pass the 'column' parameter.\n\u003c!-- See detail example [here](examples/avg.php) --\u003e\n\n### `first()`\n\nIt will return the first element of the collection.\n\n**example:**\n\n```php\n$q = new linq('data.json');\n$res = $q-\u003efrom('products')\n    -\u003ewhere('cat', '=', 1)\n    -\u003efirst();\n```\n\n\u003c!-- See detail example [here](examples/first.php). --\u003e\n\n### `last()`\n\nIt will return the last element of the collection.\n\n**example:**\n\n```php\n$q = new Linq($data);\n$res = $q-\u003efrom('products')\n    -\u003ewhere('cat', '=', 1)\n    -\u003elast();\n```\n\n\u003c!-- See detail example [here](examples/last.php). --\u003e\n\n### `nth(index)`\n\n- `index` -- index of the element to be returned.\n\nIt will return the nth element of the collection. If the given index is a **positive** value, it will return the nth element from the beginning. If the given index is a **negative** value, it will return the nth element from the end.\n\n**example:**\n\n```php\n$q = new Linq($data);\n$res = $q-\u003efrom('products')\n  -\u003ewhere('cat', '=', 1)\n  -\u003enth(2);\n```\n\n\u003c!-- See detail example [here](examples/nth.php). --\u003e\n\n### `exists()`\n\nIt will return **true** if the element is not **empty** or not **null** or not an **empty array** or not an **empty object**.\n\n**example:**\n\nLet's say you want to find how many elements are in the _'products'_ property. You can do it like:\n\n```php\n$q = new Linq($data);\n$res = $q-\u003efrom('products')\n    -\u003ewhere('cat', '=', 1)\n    -\u003eexists();\n```\n\n\u003c!-- See detail example [here](examples/exists.php). --\u003e\n\n### `groupBy(column)`\n\n- `column` -- The property by which you want to group the collection.\n\n**example:**\n\nLet's say you want to group the _'users'_ data based on the _'location'_ property. You can do it like:\n\n```php\n$q = new Linq($data);\n$res = $q-\u003efrom('users')\n    -\u003egroupBy('location')\n    -\u003eget();\n```\n\nSee detail example [here](examples/group-by.php).\n\n### `sort(order)`\n\n- `order` -- If you skip the _'order'_ property the data will be by default ordered as **ascending**. You need to pass **'desc'** as the _'order'_ parameter to sort the data in **descending** order. Also, you can pass a compare function in _'order'_ parameter to define your own logic to order the data.\n\n**Note:** This method should be used for plain Array. If you want to sort an Array of Objects you should use the **sortBy()** method described later.\n\n**example:**\n\nLet's say you want to sort the _'arr'_ data. You can do it like:\n\n```php\n$q = new Linq();\n$res = $q-\u003ecollect([7, 5, 9, 1, 3])\n    -\u003esort();\n```\n\nSee detail example [here](examples/sort.php).\n\n### `sortBy(column, order)`\n\n- `column` -- You need to pass the column name on which the sorting will be done.\n- `order` -- If you skip the _'order'_ property the data will be by default ordered as **ascending**. You need to pass **'desc'** as the _'order'_ parameter to sort the data in **descending** order. Also, you can pass a compare function in _'order'_ parameter to define your own logic to order the data.\n\n**Note:** This method should be used for Array of Objects. If you want to sort a plain Array you should use the **sort()** method described earlier.\n\n**example:**\n\nLet's say you want to sort the _'price'_ data of _'products'_. You can do it like:\n\n```php\n$q = new Linq($data);\n$res = $q-\u003efrom('products')\n    -\u003ewhere('cat', '=', 1)\n    -\u003esortBy('price', 'desc');\n```\n\n\u003c!-- See detail example [here](examples/sort-by.php). --\u003e\n\n### `reset(data)`\n\n- `data` -- can be a JSON string or a PHP array. If no data passed in the `data` parameter, the `Linq` Object instance will be reset to previously initialized data.\n\nAt any point, you might want to reset the Object instance to a completely different set of data and then query over it. You can use this method in that case.\n\n\u003c!-- See a detail example [here](examples/reset.php). --\u003e\n\n### `copy()`\n\nIt will return a complete clone of the Object instance.\n\n\u003c!-- See a detail example [here](examples/copy.php). --\u003e\n\n\u003c!-- ## Others Platform\n\nThis package has also different language support.\n\n- [JavaScript JsonQ](https://github.com/me-shaon/js-linq) developed by [Ahmed shamim](https://github.com/me-shaon)\n- [Python JsonQ](https://github.com/s1s1ty/py-linq) developed by [Shaon Shaonty](https://github.com/s1s1ty)\n- [Go JsonQ](https://github.com/thedevsaddam/golinq) developed by [Saddam H](https://github.com/thedevsaddam) - Upcoming --\u003e\n\n## Example Files\n\n\u003e There will be an example file for any of above methods soon.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpenobit%2Flinq","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpenobit%2Flinq","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpenobit%2Flinq/lists"}