{"id":24326882,"url":"https://github.com/webinarium/linode-api","last_synced_at":"2025-09-27T11:30:35.515Z","repository":{"id":62547853,"uuid":"61518578","full_name":"webinarium/linode-api","owner":"webinarium","description":"Linode API Client Library for PHP.","archived":false,"fork":false,"pushed_at":"2024-02-03T04:19:32.000Z","size":1875,"stargazers_count":9,"open_issues_count":0,"forks_count":7,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-01-10T10:14:31.509Z","etag":null,"topics":["api","linode","php"],"latest_commit_sha":null,"homepage":"https://www.linode.com/docs/api/","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/webinarium.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2016-06-20T05:12:51.000Z","updated_at":"2024-07-07T15:53:31.000Z","dependencies_parsed_at":"2024-01-12T01:20:57.715Z","dependency_job_id":"4b15f060-db46-4391-9f06-2c1d5589dcfa","html_url":"https://github.com/webinarium/linode-api","commit_stats":null,"previous_names":[],"tags_count":12,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/webinarium%2Flinode-api","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/webinarium%2Flinode-api/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/webinarium%2Flinode-api/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/webinarium%2Flinode-api/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/webinarium","download_url":"https://codeload.github.com/webinarium/linode-api/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":234429244,"owners_count":18831241,"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":["api","linode","php"],"created_at":"2025-01-17T21:14:52.047Z","updated_at":"2025-09-27T11:30:35.113Z","avatar_url":"https://github.com/webinarium.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Linode API Client Library\n\n[![PHP](https://img.shields.io/badge/PHP-8.1%2B-blue.svg)](https://secure.php.net/migration81)\n[![Latest Stable Version](https://poser.pugx.org/webinarium/linode-api/v/stable)](https://packagist.org/packages/webinarium/linode-api)\n[![Build Status](https://travis-ci.com/webinarium/linode-api.svg?branch=master)](https://travis-ci.com/github/webinarium/linode-api)\n[![Code Coverage](https://scrutinizer-ci.com/g/webinarium/linode-api/badges/coverage.png?b=master)](https://scrutinizer-ci.com/g/webinarium/linode-api/?branch=master)\n[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/webinarium/linode-api/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/webinarium/linode-api/?branch=master)\n\nThis package provides a PHP client library for [Linode API](https://www.linode.com/docs/api/).\nThe library is up-to-date with API [4.171.0](https://www.linode.com/docs/products/tools/api/release-notes/) released on 2024-02-01.\n\n## Requirements\n\nPHP needs to be a minimum version of PHP 8.1.\n\n## Installation\n\nThe recommended way to install is via Composer:\n\n```bash\ncomposer require webinarium/linode-api\n```\n\n## Usage\n\n\u003cdetails\u003e\n\u003csummary\u003eBasic Usage\u003c/summary\u003e\n\u003cbr\u003e\n\nAccess to all API endpoints goes through an instance of `LinodeClient` class, which you have to create first:\n\n```php\nuse Linode\\LinodeClient;\n\n$client = new LinodeClient();\n\n$regions = $client-\u003eregions-\u003efindAll();\n```\n\nThe example above creates an unauthenticated client which is enough to access few public endpoints like _regions_ or _kernels_.\nTo access your private data you need to provide `LinodeClient` with your access token:\n\n```php\nuse Linode\\LinodeClient;\n\n$client = new LinodeClient('03d084436a6c91fbafd5c4b20c82e5056a2e9ce1635920c30dc8d81dc7a6665c');\n\n$linodes = $client-\u003elinodes-\u003efindAll();\n```\n\nAccess token can be a manually generated _Personal Access Token_ or a retrieved one from OAuth workflow.\nYou can use [oauth2-linode](https://github.com/webinarium/oauth2-linode) library to authenticate in Linode using OAuth.\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eErrors\u003c/summary\u003e\n\u003cbr\u003e\n\nAny API request to Linode can fail.\nIn this case Linode API returns list of errors, each consists of `reason` (a human-readable error message, always included) and `field` (a specific field in the submitted JSON, `null` when not applicable).\n\nThe library throws a `LinodeException` each time a request is failed.\nThe message of the exception is always a message of the first error in the errors list.\nYou can also get all errors from the exception using its `getErrors` function.\n\n```php\nuse Linode\\Exception\\LinodeException;\nuse Linode\\LinodeClient;\nuse Linode\\LinodeInstances\\Linode;\n\n$client = new LinodeClient('03d084436a6c91fbafd5c4b20c82e5056a2e9ce1635920c30dc8d81dc7a6665c');\n\ntry {\n    $linode = $client-\u003elinodes-\u003ecreate([\n        Linode::FIELD_TYPE   =\u003e 'g6-standard-2',\n        Linode::FIELD_REGION =\u003e 'us-east',\n    ]);\n}\ncatch (LinodeException $exception) {\n    // This is the same as the reason of the very first error below.\n    $message = $exception-\u003egetMessage();\n\n    foreach ($exception-\u003egetErrors() as $error) {\n        echo $error-\u003efield;\n        echo $error-\u003ereason;\n    }\n}\n```\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eEntities and Repositories\u003c/summary\u003e\n\u003cbr\u003e\n\nThe library provides an _entity_ class for every object returned by Linode API - _linodes_, _images_, _nodebalancers_, whatever.\nAll entities are read-only, the data are accessible through properties.\n\nAlso, there is a dedicated repository for entity of each type. Most of the repositories are available through the `LinodeClient` class:\n\n```php\nuse Linode\\LinodeClient;\nuse Linode\\LinodeInstances\\Linode;\nuse Linode\\LinodeInstances\\LinodeRepositoryInterface;\n\n$client = new LinodeClient('03d084436a6c91fbafd5c4b20c82e5056a2e9ce1635920c30dc8d81dc7a6665c');\n\n/** @var LinodeRepositoryInterface $repository */\n$repository = $client-\u003elinodes;\n\n/** @var Linode $linode */\n$linode = $repository-\u003efind(123);\n\necho $linode-\u003elabel;\necho $linode-\u003ehypervisor;\n```\n\nSome entities are nested, for example `DomainRecord` objects always belong to some `Domain` object.\nA repository for such nested entities should be taken from corresponding parent entity.\nThe `LinodeClient` class contains repositories for root entities only.\n\n```php\nuse Linode\\Domains\\Domain;\nuse Linode\\Domains\\DomainRecord;\nuse Linode\\LinodeClient;\n\n$client = new LinodeClient('03d084436a6c91fbafd5c4b20c82e5056a2e9ce1635920c30dc8d81dc7a6665c');\n\n/** @var Domain $domain */\n$domain = $client-\u003edomains-\u003efindOneBy([\n    Domain::FIELD_DOMAIN =\u003e 'example.com',\n]);\n\n/** @var DomainRecord[] $records */\n$records = $domain-\u003erecords-\u003efindAll();\n\nforeach ($records as $record) {\n    echo $record-\u003etype;\n}\n```\n\nTo make it easier to find corresponding entity and repository, the library sources are structured the same way as the original API documentation.\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eRepositories and Collections\u003c/summary\u003e\n\u003cbr\u003e\n\nEach repository implements `Linode\\RepositoryInterface` and provides two following functions.\n\nThe `find` function searches for an entity by its ID:\n\n```php\nuse Linode\\LinodeClient;\nuse Linode\\LinodeInstances\\Linode;\n\n$client = new LinodeClient('03d084436a6c91fbafd5c4b20c82e5056a2e9ce1635920c30dc8d81dc7a6665c');\n\n/** @var Linode $linode */\n$linode = $client-\u003elinodes-\u003efind(123);\n```\n\nThe `findAll` function returns all entities of the type as a `Linode\\EntityCollection` object.\nSuch object implements standard `Countable` and `Iterator` interfaces:\n\n```php\nuse Linode\\LinodeClient;\nuse Linode\\LinodeInstances\\Linode;\n\n$client = new LinodeClient('03d084436a6c91fbafd5c4b20c82e5056a2e9ce1635920c30dc8d81dc7a6665c');\n\n/** @var Linode[] $linodes */\n$linodes = $client-\u003elinodes-\u003efindAll();\n\nprintf('Found %d linode(s).', count($linodes));\n\nforeach ($linodes as $linode) {\n    // ...\n}\n```\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003ePagination\u003c/summary\u003e\n\u003cbr\u003e\n\nWhen you are retrieving a list of objects from Linode API, the API returns the list paginated.\nTo make your life easier, the library manages the pagination for you internally, so you can work with a list of entities as with a simple array.\n\nFor example, let's assume you have 270 linodes in your account and need to enumerate their labels:\n\n```php\nuse Linode\\LinodeClient;\n\n$client = new LinodeClient('03d084436a6c91fbafd5c4b20c82e5056a2e9ce1635920c30dc8d81dc7a6665c');\n\n$linodes = $client-\u003elinodes-\u003efindAll();\n\nforeach ($linodes as $linode) {\n    echo $linode-\u003elabel;\n}\n```\n\nWhen you call `findAll` function in this example, only first 100 entities are loaded (100 is a default page size in the API).\nOnce you reach 101st entity in your enumeration, the library makes another call for next 100 linodes, and so on.\nAs result, the library will make three API requests for your 270 linodes, but it's completely transparent for you.\nOf course, extra requests are performed only when needed, so if you break your enumeration in the middle, remaining entities won't be requested at all.\n\nAlso, the retrieved entities are cached per collection, so it's safe to enumerate the same collection multiple times:\n\n```php\nuse Linode\\LinodeClient;\n\n$client = new LinodeClient('03d084436a6c91fbafd5c4b20c82e5056a2e9ce1635920c30dc8d81dc7a6665c');\n\n$linodes = $client-\u003elinodes-\u003efindAll();\n\n// This will make three API requests.\nforeach ($linodes as $linode) {\n    echo $linode-\u003elabel;\n}\n\n// This will make no API requests at all.\nforeach ($linodes as $linode) {\n    echo $linode-\u003etype;\n}\n\n$linodes2 = $client-\u003elinodes-\u003efindAll();\n\n// This will make three API requests again, as this is another collection.\nforeach ($linodes2 as $linode) {\n    echo $linode-\u003etype;\n}\n```\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eSorting\u003c/summary\u003e\n\u003cbr\u003e\n\nThe Linode API supports sorting of the requested objects, which can be specified in two optional parameters of the `findAll` function:\n\n```php\nuse Linode\\LinodeClient;\nuse Linode\\LinodeInstances\\Linode;\nuse Linode\\RepositoryInterface;\n\n$client = new LinodeClient('03d084436a6c91fbafd5c4b20c82e5056a2e9ce1635920c30dc8d81dc7a6665c');\n\n$linodes = $client-\u003elinodes-\u003efindAll(Linode::FIELD_LABEL, RepositoryInterface::SORT_DESC);\n```\n\nThe first parameter is the name of the field to sort entities by.\nEvery entity class contains useful constants so you don't have to hardcode field names.\n\nThe second parameter is a sorting direction and equals to `Linode\\RepositoryInterface::SORT_ASC` if omitted.\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eFiltering (simple queries)\u003c/summary\u003e\n\u003cbr\u003e\n\nThe Linode API supports filtering of the requested objects, which is addressed by the same `Linode\\RepositoryInterface` interface via `findBy`, `findOneBy`, and `query` functions.\n\nThe `findBy` function accepts array of criterias as the first parameter.\nAll the criterias are joined via logical `AND` operation.\n\n```php\nuse Linode\\LinodeClient;\nuse Linode\\LinodeInstances\\Linode;\n\n$client = new LinodeClient('03d084436a6c91fbafd5c4b20c82e5056a2e9ce1635920c30dc8d81dc7a6665c');\n\n$linodes = $client-\u003elinodes-\u003efindBy([\n    Linode::FIELD_REGION =\u003e 'us-west',\n    Linode::FIELD_TAGS   =\u003e 'app-server',\n]);\n```\n\nSecond and third parameters of the function are for sorting and work exactly as the corresponding parameters of the `findAll` function.\n\nThe `findBy` function returns a collection, which can be empty if nothing is found.\nWhen you need to retrieve a single object using filters, you may use the `findOneBy` function, which accepts an array of criterias as the only parameter.\n\n```php\nuse Linode\\LinodeClient;\nuse Linode\\LinodeInstances\\Linode;\n\n$client = new LinodeClient('03d084436a6c91fbafd5c4b20c82e5056a2e9ce1635920c30dc8d81dc7a6665c');\n\n$linode = $client-\u003elinodes-\u003efindOneBy([\n    Linode::FIELD_LABEL =\u003e 'mysql-server-02',\n]);\n```\n\nIf nothing is found, the function returns `null`.\nIf more than one entity is found, the function raises a `LinodeException`.\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eFiltering (complex queries)\u003c/summary\u003e\n\u003cbr\u003e\n\nThe last of functions mentioned above - `query` - lets you make complex requests using query language of the Linode API.\n\nThe API query language assumes you convert your conditions to JSON, which actually makes them hard to read, debug, and maintain.\nFor example, current API documentation suggests the following JSON object to get all Linode Types which are either _standard_ or _highmem_ class, or have between 12 and 20 vcpus:\n\n```json\n{\n  \"+or\": [\n    {\n      \"+or\": [\n        {\n          \"class\": \"standard\"\n        },\n        {\n          \"class\": \"highmem\"\n        }\n      ]\n    },\n    {\n      \"+and\": [\n        {\n          \"vcpus\": {\n            \"+gte\": 12\n          }\n        },\n        {\n          \"vcpus\": {\n            \"+lte\": 20\n          }\n        }\n      ]\n    }\n  ]\n}\n```\n\nThe `query` function lets you write your conditions using more human-readable expressions which are passed as a string to the first parameter.\nThe above example can be implemented as following:\n\n```php\nuse Linode\\LinodeClient;\n\n$client = new LinodeClient();\n\n$types = $client-\u003elinodeTypes-\u003equery('(class == \"standard\" or class == \"highmem\") or (vcpus \u003e= 12 and vcpus \u003c= 20)');\n\nforeach ($types as $type) {\n    echo $type-\u003eclass;\n    echo $type-\u003evcpus;\n}\n```\n\nAll Linode API operators are supported by the library using following lexems:\n\n\u003ctable\u003e\n\u003ctr\u003e\u003ctd\u003e==\u003c/td\u003e\u003ctd\u003eequals\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003e!=\u003c/td\u003e\u003ctd\u003edoesn't equal\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003e\u003c\u003c/td\u003e\u003ctd\u003eis greater than\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003e\u003c=\u003c/td\u003e\u003ctd\u003eis less than or equal to\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003e\u003e\u003c/td\u003e\u003ctd\u003eis greater than\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003e\u003e=\u003c/td\u003e\u003ctd\u003eis greater than or equal to\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003e~\u003c/td\u003e\u003ctd\u003econtains a substring\u003c/td\u003e\u003c/tr\u003e\n\u003c/table\u003e\n\nIn case of syntax error in your expression, the library will raise a `LinodeException` with a list of all found errors.\n\nIf you need to create your expression using some variables, you may use parameterized expression, as in the example below:\n\n```php\nuse Linode\\LinodeClient;\n\n$client = new LinodeClient();\n\n$parameters = [\n    'class1' =\u003e 'standard',\n    'class2' =\u003e 'highmem',\n    'min'    =\u003e 12,\n    'max'    =\u003e 20,\n];\n\n$types = $client-\u003elinodeTypes-\u003equery('(class == :class1 or class == :class2) or (vcpus \u003e= :min and vcpus \u003c= :max)', $parameters);\n```\n\nEach parameter starts with a colon, and the whole set of parameters is provided once as an array.\n\nAnd, just like `findAll` and `findBy` functions, the `query` function has two last optional parameters for sorting:\n\n```php\nuse Linode\\LinodeClient;\nuse Linode\\LinodeTypes\\LinodeType;\nuse Linode\\RepositoryInterface;\n\n$client = new LinodeClient();\n\n$parameters = [\n    'class1' =\u003e 'standard',\n    'class2' =\u003e 'highmem',\n    'min'    =\u003e 12,\n    'max'    =\u003e 20,\n];\n\n$types = $client-\u003elinodeTypes-\u003equery(\n    '(class == :class1 or class == :class2) or (vcpus \u003e= :min and vcpus \u003c= :max)',\n    $parameters,\n    LinodeType::FIELD_MEMORY,\n    RepositoryInterface::SORT_DESC);\n```\n\u003c/details\u003e\n\n## Development\n\n```bash\n./bin/php-cs-fixer fix\nXDEBUG_MODE=coverage ./bin/phpunit --coverage-text\n```\n\n## Contributing\n\nPlease see [CONTRIBUTING](https://github.com/webinarium/linode-api/blob/master/CONTRIBUTING.md) for details.\n\n## Credits\n\n- [Artem Rodygin](https://github.com/webinarium)\n\n## License\n\nThe MIT License (MIT). Please see [License File](https://github.com/webinarium/linode-api/blob/master/LICENSE) for more information.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwebinarium%2Flinode-api","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwebinarium%2Flinode-api","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwebinarium%2Flinode-api/lists"}