1. Go to this page and download the library: Download saintsystems/odata-client library. Choose the download type require.
2. Extract the ZIP file and open the index.php.
3. Add this code to the index.php.
<?php
require_once('vendor/autoload.php');
/* Start to develop here. Best regards https://php-download.com/ */
saintsystems / odata-client example snippets
use SaintSystems\OData\ODataClient;
use SaintSystems\OData\GuzzleHttpProvider;
$httpProvider = new GuzzleHttpProvider();
$odataClient = new ODataClient($odataServiceUrl, null, $httpProvider);
use SaintSystems\OData\ODataClient;
use SaintSystems\OData\Psr17HttpProvider;
// Example using Symfony HTTP Client with Nyholm PSR-7
$httpClient = new \Symfony\Component\HttpClient\Psr18Client();
$requestFactory = new \Nyholm\Psr7\Factory\Psr17Factory();
$streamFactory = new \Nyholm\Psr7\Factory\Psr17Factory();
$httpProvider = new Psr17HttpProvider($httpClient, $requestFactory, $streamFactory);
$odataClient = new ODataClient($odataServiceUrl, null, $httpProvider);
aintSystems\OData\ODataClient;
use SaintSystems\OData\GuzzleHttpProvider;
class UsageExample
{
public function __construct()
{
$odataServiceUrl = 'https://services.odata.org/V4/TripPinService';
$httpProvider = new GuzzleHttpProvider();
$odataClient = new ODataClient($odataServiceUrl, null, $httpProvider);
// Retrieve all entities from the "People" Entity Set
$people = $odataClient->from('People')->get();
// Or retrieve a specific entity by the Entity ID/Key
try {
$person = $odataClient->from('People')->find('russellwhyte');
echo "Hello, I am $person->FirstName ";
} catch (Exception $e) {
echo $e->getMessage();
}
// Want to only select a few properties/columns?
$people = $odataClient->from('People')->select('FirstName','LastName')->get();
}
}
$example = new UsageExample();
use SaintSystems\OData\ODataClient;
use SaintSystems\OData\GuzzleHttpProvider;
$httpProvider = new GuzzleHttpProvider();
$odataClient = new ODataClient($odataServiceUrl, null, $httpProvider);
// Method 1: Set headers on the client (applies to all requests)
$odataClient->setHeaders([
'Authorization' => 'Bearer your-token-here',
'X-Custom-Header' => 'MyCustomValue',
'X-Client-Version' => '1.0.0'
]);
// Method 2: Add a single header to the client
$odataClient->addHeader('X-Request-ID', uniqid());
// Method 3: Add headers to specific queries using the fluent interface
$people = $odataClient->from('People')
->withHeader('X-Query-Context', 'get-all-people')
->withHeaders([
'X-Debug' => 'true',
'X-Performance-Track' => 'enabled'
])
->get();
// Headers set on the client persist across requests
$person = $odataClient->from('People')->find('russellwhyte');
// Query-specific headers only apply to that request
$airlines = $odataClient->from('Airlines')
->withHeader('X-Data-Source', 'airlines-api')
->get();
use SaintSystems\OData\ODataClient;
use SaintSystems\OData\GuzzleHttpProvider;
$httpProvider = new GuzzleHttpProvider();
$odataClient = new ODataClient($odataServiceUrl, null, $httpProvider);
// Method 1: Add custom options using string format
$people = $odataClient->from('People')
->addOption('timeout=30')
->addOption('format=minimal')
->get();
// Results in: /People?timeout=30&format=minimal
// Method 2: Add custom options using array format
$people = $odataClient->from('People')
->addOption(['timeout' => '30', 'debug' => 'true'])
->get();
// Results in: /People?timeout=30&debug=true
// Method 3: Mix with standard OData parameters
$people = $odataClient->from('People')
->select('FirstName', 'LastName')
->where('FirstName', 'Russell')
->addOption('version=2.0')
->get();
// Results in: /People?$select=FirstName,LastName&$filter=FirstName eq 'Russell'&version=2.0
// Method 4: Multiple addOption calls are merged (not overwritten)
$people = $odataClient->from('People')
->addOption('timeout=30')
->addOption('format=minimal')
->addOption(['debug' => 'true']);
// Results in: /People?timeout=30&format=minimal&debug=true
// Custom option keys are validated:
// ✓ Valid: 'timeout', 'custom_param', 'kebab-case', 'camelCase'
// ✗ Invalid: '$reserved' (starts with $), 'invalid key!' (special chars)
use SaintSystems\OData\ODataClient;
use SaintSystems\OData\GuzzleHttpProvider;
class CustomTimeoutODataClient extends ODataClient {
private $customTimeout;
public function __construct($baseUrl, $authProvider = null, $httpProvider = null, $timeout = 30) {
parent::__construct($baseUrl, $authProvider, $httpProvider);
$this->customTimeout = $timeout;
}
protected function createRequest($method, $requestUri) {
$request = parent::createRequest($method, $requestUri);
$request->setTimeout($this->customTimeout);
return $request;
}
}
// Usage with custom timeout
$httpProvider = new GuzzleHttpProvider();
$client = new CustomTimeoutODataClient('https://api.example.com/odata', null, $httpProvider, 60);
$result = $client->from('Products')->get(); // Uses 60-second timeout
use SaintSystems\OData\ODataClient;
use SaintSystems\OData\GuzzleHttpProvider;
$httpProvider = new GuzzleHttpProvider();
$client = new ODataClient('https://services.odata.org/V4/TripPinService', null, $httpProvider);
// Get a person with address information
$person = $client->from('People')->find('russellwhyte');
// Access nested properties directly
$city = $person->AddressInfo[0]->City; // Object-style access
$country = $person->AddressInfo[0]->CountryRegion; // Deep nesting supported
// Complex nested structures work naturally
if ($person->Settings && $person->Settings->Preferences) {
$theme = $person->Settings->Preferences->Theme;
}
// Safe access with dot notation - returns null if any part doesn't exist
$city = $person->getProperty('AddressInfo.0.City');
$country = $person->getProperty('AddressInfo.0.CountryRegion');
$theme = $person->getProperty('Settings.Preferences.Theme');
// Works with array indices and object properties
$firstFriendName = $person->getProperty('Friends.0.FirstName');
$homeAddress = $person->getProperty('AddressInfo.0.Address');
// Check existence using hasProperty()
if ($person->hasProperty('AddressInfo.0.City')) {
$city = $person->getProperty('AddressInfo.0.City');
}
// Also works with isset() for object-style access
if (isset($person->AddressInfo[0]->City)) {
$city = $person->AddressInfo[0]->City;
}
// Check for deeply nested paths
if ($person->hasProperty('Settings.Preferences.AutoSave')) {
$autoSave = $person->getProperty('Settings.Preferences.AutoSave');
}
// Get people with address information
$people = $client->select('UserName,FirstName,LastName,AddressInfo')
->from('People')
->get();
foreach ($people as $person) {
echo "Person: " . $person->FirstName . " " . $person->LastName . "\n";
// Access nested address info - remains as array for easy filtering
$addresses = $person->AddressInfo;
// Filter addresses by type
$homeAddresses = array_filter($addresses, function($address) {
return isset($address['Type']) && $address['Type'] === 'Home';
});
// Access properties within filtered results
foreach ($homeAddresses as $address) {
// Convert to Entity for object-style access
$addrEntity = new \SaintSystems\OData\Entity($address);
echo " Home Address: " . $addrEntity->Address . ", " . $addrEntity->City . "\n";
}
}
// Query for folders with nested Info and Children data
$folders = $client->select('Id,Name,CreatorNameShort,Info,Info/IsAHomeFolder,Children/Id,Children/Name')
->from('Items')
->where('HasChildren', true)
->get();
foreach ($folders as $folder) {
echo "Folder: " . $folder->Name . "\n";
echo "Creator: " . $folder->CreatorNameShort . "\n";
// Access nested Info properties
if ($folder->Info) {
echo "Is Home Folder: " . ($folder->Info->IsAHomeFolder ? 'Yes' : 'No') . "\n";
// Safe navigation for optional nested properties
if ($folder->hasProperty('Info.Settings.Theme')) {
echo "Theme: " . $folder->getProperty('Info.Settings.Theme') . "\n";
}
}
// Work with Children collection
if ($folder->Children) {
echo "Children:\n";
// Filter children by type
$subfolders = array_filter($folder->Children, function($child) {
return $child['FileSizeBytes'] == 0; // Folders have 0 file size
});
foreach ($subfolders as $subfolder) {
echo " - " . $subfolder['Name'] . " (ID: " . $subfolder['Id'] . ")\n";
}
}
echo "\n";
}
// Select specific nested properties
$result = $client->select('Id,Name,Info/IsAHomeFolder,Children/Name,AddressInfo/City')
->from('Items')
->get();
// Use in where clauses (if supported by the OData service)
$homeItems = $client->from('Items')
->where('Info/IsAHomeFolder', true)
->get();
// Expand related data and access nested properties
$peopleWithTrips = $client->from('People')
->expand('Trips')
->get();
foreach ($peopleWithTrips as $person) {
foreach ($person->Trips as $trip) {
// Access nested trip properties
$tripEntity = new \SaintSystems\OData\Entity($trip);
echo $person->FirstName . " has trip: " . $tripEntity->Name . "\n";
}
}
use SaintSystems\OData\ODataClient;
use SaintSystems\OData\GuzzleHttpProvider;
$httpProvider = new GuzzleHttpProvider();
$client = new ODataClient('https://services.odata.org/V4/TripPinService', null, $httpProvider);
// Find people who have any completed trips
$peopleWithCompletedTrips = $client->from('People')
->whereAny('Trips', function($query) {
$query->where('Status', 'Completed');
})
->get();
// Generates: People?$filter=Trips/any(t: t/Status eq 'Completed')
// Find people where all their trips are high-budget
$peopleWithAllHighBudgetTrips = $client->from('People')
->whereAll('Trips', function($query) {
$query->where('Budget', '>', 1000);
})
->get();
// Generates: People?$filter=Trips/all(t: t/Budget gt 1000)