1. Go to this page and download the library: Download andydefer/php-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/ */
andydefer / php-client example snippets
// ❌ Sans ce package - Fragile, non typé, difficile à maintenir
$response = $client->get('https://api.example.com/users');
$data = json_decode($response->getBody(), true);
$userName = $data['data']['user']['name'] ?? null;
// ↑ Si l'API change, tout casse sans prévenir
// ↑ Pas d'autocomplétion
// ↑ Pas de typage
use AndyDefer\PhpClient\Abstracts\Request;
use AndyDefer\PhpClient\Enums\HttpMethod;
use AndyDefer\PhpClient\ValueObjects\UrlVO;
use AndyDefer\PhpClient\ValueObjects\RequestBodyVO;
use AndyDefer\PhpClient\Abstracts\Struct;
use AndyDefer\PhpClient\Enums\ContentType;
final class GetUserRequest extends Request
{
private ?int $userId = null;
public function setUserId(int $userId): self
{
$this->userId = $userId;
return $this;
}
protected function setMethod(): HttpMethod
{
return HttpMethod::GET;
}
protected function setUrl(): UrlVO
{
$url = new UrlVO('https://api.example.com/users');
if ($this->userId !== null) {
$url = $url->withPath('/users/' . $this->userId);
}
return $url;
}
protected function setBody(): RequestBodyVO
{
return new RequestBodyVO(
new class extends Struct {},
ContentType::JSON
);
}
}
use AndyDefer\PhpClient\Abstracts\Response;
final class UserListResponse extends Response
{
public function getUsers(): array
{
return $this->getBody()->getValue()->users ?? [];
}
public function getTotal(): int
{
return $this->getBody()->getValue()->total ?? 0;
}
public static function getStructClass(): string
{
return UserListStruct::class;
}
}
use AndyDefer\PhpClient\Clients\ClientService;
$client = new ClientService();
$response = $client->get(
'https://api.example.com/users', // URI (absolue ou relative)
$request, // Instance de Request
UserListResponse::class // Classe de réponse attendue
);
use AndyDefer\PhpClient\ValueObjects\OptionsVO;
$options = new OptionsVO();
$options
// Timeouts
->setTimeout(30) // Délai d'attente global
->setConnectTimeout(10) // Délai de connexion
// SSL
->setVerify(true) // Vérification SSL
->setCert('/path/to/cert.pem') // Certificat SSL
->setSslKey('/path/to/key.pem') // Clé SSL
// Redirections
->setAllowRedirects(false) // Suivre les redirections
->setMaxRedirects(5) // Nombre max de redirections
// Proxy
->setProxy('tcp://localhost:8080') // Proxy
->setNoProxy(['.example.com']) // Exclure du proxy
// Authentification
->setAuth(['username', 'password']) // Basic auth
// Environnement
->setBaseUri('https://api.example.com') // Base URI
->setQuery(['page' => 1]) // Query params
->setDecodeContent(true) // Décoder le contenu
->setHttpErrors(false); // Ne pas lancer d'exception sur erreur HTTP
use AndyDefer\PhpClient\ValueObjects\RequestBodyVO;
use AndyDefer\PhpClient\Abstracts\Struct;
// Corps JSON
$struct = new UserCreateStruct(name: 'John', email: '[email protected]');
$body = new RequestBodyVO($struct, ContentType::JSON);
$json = $body->toString(); // '{"name":"John","email":"..."}'
$array = $body->toArray(); // ['name' => 'John', 'email' => '...']
$struct = $body->getStruct(); // UserCreateStruct
// Corps formulaire
$body = new RequestBodyVO($struct, ContentType::FORM);
$formData = $body->toString(); // 'name=John&email=...'
use AndyDefer\PhpClient\ValueObjects\ResponseBodyVO;
$body = new ResponseBodyVO(
$jsonResponse, // Chaîne JSON
UserListStruct::class, // Classe de structure
ContentType::JSON // Content-Type attendu
);
$struct = $body->getValue(); // UserListStruct hydraté
$formatted = $body->format(); // stdClass ou array
$isEmpty = $body->isEmpty(); // true si le corps est vide
$isValid = $body->isValidJson(); // true si le JSON est valide
use AndyDefer\PhpClient\ValueObjects\UrlVO;
$url = new UrlVO('https://api.example.com:8080/v2/users?page=1#section');
$url->getScheme(); // 'https'
$url->getHost(); // 'api.example.com'
$url->getPort(); // 8080
$url->getPath(); // '/v2/users'
$url->getQuery(); // UrlQueryVO avec 'page=1'
$url->getFragment(); // 'section'
$url->getBaseUrl(); // 'https://api.example.com:8080'
$url->getFullPath(); // '/v2/users?page=1#section'
// Modification (retourne une nouvelle instance)
$newUrl = $url->withPath('/v3/users');
$newUrl = $url->withQuery(new UrlQueryVO('limit=10'));
$newUrl = $url->withFragment(null);
use AndyDefer\PhpClient\ValueObjects\UrlQueryVO;
$query = new UrlQueryVO('page=1&limit=10');
$query = $query
->withParameter('page', 2)
->withParameter('sort', 'asc')
->withoutParameter('limit');
echo $query->toString(); // 'page=2&sort=asc'
// Intégration avec UrlVO
$url = new UrlVO('https://api.example.com/users?page=1');
$newUrl = $url->withQuery($query);
echo $newUrl->getValue(); // 'https://api.example.com/users?page=2&sort=asc'
declare(strict_types=1);
ts\Graph;
use AndyDefer\PhpClient\Abstracts\Request;
use AndyDefer\PhpClient\Abstracts\Response;
use AndyDefer\PhpClient\Abstracts\Struct;
use AndyDefer\PhpClient\Clients\ClientService;
use AndyDefer\PhpClient\Enums\ContentType;
use AndyDefer\PhpClient\Enums\HttpMethod;
use AndyDefer\PhpClient\ValueObjects\RequestBodyVO;
use AndyDefer\PhpClient\ValueObjects\UrlQueryVO;
use AndyDefer\PhpClient\ValueObjects\UrlVO;
// 1. Enum - Centralisation des URLs avec UrlVO
enum PlaceholderEndpoint: string
{
case POSTS = 'https://jsonplaceholder.typicode.com/posts';
case COMMENTS = 'https://jsonplaceholder.typicode.com/comments';
public function getUrl(): UrlVO
{
return new UrlVO($this->value);
}
public function withId(int $id): UrlVO
{
$baseUrl = $this->getUrl();
$path = parse_url($this->value, PHP_URL_PATH) . '/' . $id;
return $baseUrl->withPath($path);
}
public function withQuery(array $params): UrlVO
{
$baseUrl = $this->getUrl();
$query = http_build_query($params);
return $baseUrl->withQuery(new UrlQueryVO($query));
}
}
// 2. Graph
final class PostGraph extends Graph
{
public function __construct(
public readonly int $userId,
public readonly int $id,
public readonly string $title,
public readonly string $body,
) {}
}
final class CommentGraph extends Graph
{
public function __construct(
public readonly int $postId,
public readonly int $id,
public readonly string $name,
public readonly string $email,
public readonly string $body,
) {}
}
// 3. Struct
final class PostListStruct extends Struct
{
public function __construct(
public readonly array $posts,
) {}
}
final class CommentListStruct extends Struct
{
public function __construct(
public readonly array $comments,
) {}
}
final class CreatedPostStruct extends Struct
{
public function __construct(
public readonly int $id,
public readonly string $title,
public readonly string $body,
public readonly int $user_id,
) {}
}
final class CreatePostStruct extends Struct
{
public function __construct(
public readonly string $title,
public readonly string $body,
public readonly int $userId,
) {}
}
// 4. Requests avec UrlVO
final class GetPostsRequest extends Request
{
protected function setMethod(): HttpMethod
{
return HttpMethod::GET;
}
protected function setUrl(): UrlVO
{
return PlaceholderEndpoint::POSTS->getUrl();
}
protected function setBody(): RequestBodyVO
{
return new RequestBodyVO(
new class extends Struct {},
ContentType::JSON
);
}
}
final class GetCommentsRequest extends Request
{
private ?int $postId = null;
public function setPostId(int $postId): self
{
$this->postId = $postId;
return $this;
}
protected function setMethod(): HttpMethod
{
return HttpMethod::GET;
}
protected function setUrl(): UrlVO
{
if ($this->postId !== null) {
return PlaceholderEndpoint::COMMENTS->withQuery(['postId' => $this->postId]);
}
return PlaceholderEndpoint::COMMENTS->getUrl();
}
protected function setBody(): RequestBodyVO
{
return new RequestBodyVO(
new class extends Struct {},
ContentType::JSON
);
}
}
final class GetCommentRequest extends Request
{
private int $id = 0;
public function setId(int $id): self
{
$this->id = $id;
return $this;
}
protected function setMethod(): HttpMethod
{
return HttpMethod::GET;
}
protected function setUrl(): UrlVO
{
return PlaceholderEndpoint::COMMENTS->withId($this->id);
}
protected function setBody(): RequestBodyVO
{
return new RequestBodyVO(
new class extends Struct {},
ContentType::JSON
);
}
}
final class CreatePostRequest extends Request
{
private string $title = '';
private string $content = '';
private int $userId = 0;
public function setTitle(string $title): self
{
$this->title = $title;
return $this;
}
public function setContent(string $content): self
{
$this->content = $content;
return $this;
}
public function setUserId(int $userId): self
{
$this->userId = $userId;
return $this;
}
protected function setMethod(): HttpMethod
{
return HttpMethod::POST;
}
protected function setUrl(): UrlVO
{
return PlaceholderEndpoint::POSTS->getUrl();
}
protected function setBody(): RequestBodyVO
{
$struct = new CreatePostStruct(
title: $this->title,
body: $this->content,
userId: $this->userId
);
return new RequestBodyVO($struct, ContentType::JSON);
}
}
// 5. Responses
final class PostListResponse extends Response
{
public function getPosts(): array
{
$data = $this->getBody()->format();
$posts = [];
foreach ($data as $item) {
$posts[] = PostGraph::from($item);
}
return $posts;
}
public static function getStructClass(): string
{
return PostListStruct::class;
}
}
final class CommentListResponse extends Response
{
public function getComments(): array
{
$data = $this->getBody()->format();
$comments = [];
foreach ($data as $item) {
$comments[] = CommentGraph::from($item);
}
return $comments;
}
public static function getStructClass(): string
{
return CommentListStruct::class;
}
}
final class CommentResponse extends Response
{
public function getComment(): CommentGraph
{
$data = $this->getBody()->format();
return CommentGraph::from($data);
}
public static function getStructClass(): string
{
return CommentStruct::class;
}
}
final class CreatePostResponse extends Response
{
public function getCreatedPost(): CreatedPostStruct
{
$data = $this->getBody()->format();
if (is_object($data)) {
$data = (array) $data;
}
return new CreatedPostStruct(
id: (int) ($data['id'] ?? 0),
title: (string) ($data['title'] ?? ''),
body: (string) ($data['body'] ?? ''),
user_id: (int) ($data['user_id'] ?? 0)
);
}
public function getId(): int
{
return $this->getCreatedPost()->id;
}
public static function getStructClass(): string
{
return CreatedPostStruct::class;
}
}
// 6. Client
class JsonPlaceholderClient
{
private ClientService $client;
public function __construct()
{
$this->client = new ClientService();
}
public function getPosts(): array
{
$request = new GetPostsRequest();
$response = $this->client->get(
PlaceholderEndpoint::POSTS->getUrl()->getValue(),
$request,
PostListResponse::class
);
return $response->getPosts();
}
public function getComments(?int $postId = null): array
{
$request = new GetCommentsRequest();
if ($postId !== null) {
$request->setPostId($postId);
}
$response = $this->client->get(
PlaceholderEndpoint::COMMENTS->getUrl()->getValue(),
$request,
CommentListResponse::class
);
return $response->getComments();
}
public function getComment(int $id): CommentGraph
{
$request = new GetCommentRequest();
$request->setId($id);
$response = $this->client->get(
PlaceholderEndpoint::COMMENTS->withId($id)->getValue(),
$request,
CommentResponse::class
);
return $response->getComment();
}
public function createPost(string $title, string $content, int $userId): CreatedPostStruct
{
$request = new CreatePostRequest();
$request
->setTitle($title)
->setContent($content)
->setUserId($userId);
$request->getHeaders()
->setContentType(ContentType::JSON)
->setAccept(ContentType::JSON);
$response = $this->client->post(
PlaceholderEndpoint::POSTS->getUrl()->getValue(),
$request,
CreatePostResponse::class
);
return $response->getCreatedPost();
}
}
// 7. Utilisation avec HeadersVO et OptionsVO
$client = new JsonPlaceholderClient();
// Récupérer tous les posts
$posts = $client->getPosts();
echo "Posts: " . count($posts) . "\n";
// Récupérer un commentaire
$comment = $client->getComment(1);
echo "Commentaire: " . $comment->name . "\n";
// Créer un post avec headers et options
$request = new CreatePostRequest();
$request
->setTitle('Mon titre')
->setContent('Mon contenu')
->setUserId(1);
$request->getHeaders()
->setAuthorization('token-123')
->setContentType(ContentType::JSON)
->setAccept(ContentType::JSON)
->setXRequestId('req-123-456');
$request->getOptions()
->setTimeout(30)
->setConnectTimeout(10)
->setHttpErrors(false);
$response = $client->post(
PlaceholderEndpoint::POSTS->getUrl()->getValue(),
$request,
CreatePostResponse::class
);
$created = $response->getCreatedPost();
echo "Post créé: " . $created->id . "\n";
final class PokemonListStruct extends Struct
{
public function __construct(
public readonly int $count,
public readonly ?string $next,
public readonly ?string $previous,
public readonly PokemonCollection $results,
) {}
}
// Utilisation
$struct = PokemonListStruct::fromJson($json);
$json = $struct->encode(ContentType::JSON);
final class TypeGraph extends Graph
{
public function __construct(
public readonly string $name,
public readonly string $url,
) {}
}
// Hydratation automatique
$type = TypeGraph::from([
'name' => 'grass',
'url' => 'https://pokeapi.co/api/v2/type/12/'
]);