PHPackages                             keytd/dynamic-backend-client-php - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [API Development](/categories/api)
4. /
5. keytd/dynamic-backend-client-php

ActiveLibrary[API Development](/categories/api)

keytd/dynamic-backend-client-php
================================

PHP client (GET-only) for Dynamic Backend API included alongside the JS library.

00JavaScriptCI failing

Since Jan 11Pushed 4mo agoCompare

[ Source](https://github.com/KeyTechAndDesign/dynamic-backend-client)[ Packagist](https://packagist.org/packages/keytd/dynamic-backend-client-php)[ RSS](/packages/keytd-dynamic-backend-client-php/feed)WikiDiscussions main Synced 1mo ago

READMEChangelogDependenciesVersions (1)Used By (0)

Dynamic Backend Client
======================

[](#dynamic-backend-client)

[![npm version](https://camo.githubusercontent.com/76b44b485c88d1824c26e831fc22b8e9f363bec88bc5dc2e1848f9f3cc20b3a1/68747470733a2f2f696d672e736869656c64732e696f2f6e706d2f762f406b657974642f64796e616d69632d6261636b656e642d636c69656e742e737667)](https://www.npmjs.com/package/@keytd/dynamic-backend-client)[![License: MIT](https://camo.githubusercontent.com/fdf2982b9f5d7489dcf44570e714e3a15fce6253e0cc6b5aa61a075aac2ff71b/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d4d49542d79656c6c6f772e737667)](https://opensource.org/licenses/MIT)[![Node.js Version](https://camo.githubusercontent.com/e2a7a89b64818394593854993f397a544d96514b6f27a41edcaa8fd6bd673b54/68747470733a2f2f696d672e736869656c64732e696f2f6e6f64652f762f406b657974642f64796e616d69632d6261636b656e642d636c69656e742e737667)](https://nodejs.org)

A JavaScript client library for interacting with the Dynamic Backend API. This library provides a clean, type-documented interface for working with blog content and dynamic tables.

> **Note:** This library only supports GET requests and does not require authorization. It is designed for read-only operations with public APIs.

📋 Table of Contents
-------------------

[](#-table-of-contents)

- [✨ Features](#-features)
- [📦 Installation](#-installation)
- [🚀 Quick Start](#-quick-start)
- [📚 API Reference](#-api-reference)
    - [ApiClient](#apiclient)
    - [BlogClient](#blogclient)
    - [TableClient](#tableclient)
    - [Localization Utility](#localization-utility)
- [❌ Error Handling](#-error-handling)
- [🌐 Multilingual Support](#-multilingual-support)
- [🔄 Compatibility](#-compatibility)
- [👥 Contributing](#-contributing)
- [📄 License](#-license)

✨ Features
----------

[](#-features)

- 🔄 **Framework Agnostic** - Works with any JavaScript environment that supports the Fetch API
- 📊 **Dynamic Tables** - Access and query dynamic database tables
- 📝 **Blog Content** - Retrieve blog posts, categories, tags, and comments
- 🌐 **Multilingual Support** - Built-in support for multilingual content
- 🔍 **Filtering &amp; Pagination** - Filter records and paginate results
- 🛡️ **Type Definitions** - Complete TypeScript definitions for better development experience
- 🚀 **Lightweight** - Minimal dependencies for faster loading
- 🧩 **Modular Design** - Use only the components you need
- 📦 **Optional Request Caching** - Built-in caching mechanism that can be enabled for improved performance and reduced API calls
- 🌍 **Client-side Localization** - Utilities for handling localized fields in data objects

📦 Installation
--------------

[](#-installation)

```
# Using npm
npm install @keytd/dynamic-backend-client

# Using yarn
yarn add @keytd/dynamic-backend-client

# Using pnpm
pnpm add @keytd/dynamic-backend-client
```

### PHP (Composer) Installation

[](#php-composer-installation)

This repository now includes a lightweight PHP implementation of the Dynamic Backend Client for read-only GET access.

You can add it to your project in several ways depending on your workflow:

1. Packagist (planned)

- If/when the PHP package is published to Packagist, you will be able to require it normally: composer require keytd/dynamic-backend-client-php

2. VCS repository (use directly from GitHub)

- Add this repository as a Composer VCS repository and require the PHP package name from composer.json in this repo:

```
{
  "repositories": [
    { "type": "vcs", "url": "https://github.com/keytd/dynamic-backend-client" }
  ],
  "require": {
    "php": ">=8.0",
    "keytd/dynamic-backend-client-php": "dev-main"
  }
}
```

Then run:

```
composer update keytd/dynamic-backend-client-php
```

3. Local path repository (use a local clone)

- If you have the repository checked out locally, you can reference it via a path repository:

```
{
  "repositories": [
    { "type": "path", "url": "../dynamic-backend-client" }
  ],
  "require": {
    "php": ">=8.0",
    "keytd/dynamic-backend-client-php": "dev-main"
  }
}
```

Then run:

```
composer update keytd/dynamic-backend-client-php
```

4. Copy-only (no VCS)

- Copy the php/ directory into your project and set up PSR-4 autoloading to that folder:

```
{
  "name": "your-vendor/your-project",
  "require": {
    "php": ">=8.0"
  },
  "autoload": {
    "psr-4": {
      "KeyTD\\DynamicBackendClient\\": "php/"
    }
  }
}
```

Then run:

```
composer dump-autoload
```

### PHP Client Status

[](#php-client-status)

- Scope: Read-only, GET-only client that mirrors the JS client's surface for Blog and Tables plus localization utilities.
- Implemented: ApiClient (cURL-based HTTP, timeout, X-Schema header, optional in-memory caching), BlogClient (posts, categories, tags, comments), TableClient (list/info/records/record by id with client-side localization), LocalizeUtil.
- Tested: PHPUnit test suite included (no network calls; uses stubs). Run with composer test.
- Requirements: PHP 8.0+, ext-curl enabled.
- Not included: POST/PUT/PATCH/DELETE, authentication flows.

### Publishing the PHP package to Packagist

[](#publishing-the-php-package-to-packagist)

You do not need a separate repository for the PHP client. Packagist can consume this same repository (monorepo) as long as a valid composer.json is present at the repository root — which it is. We’ve also added a .gitattributes file to ensure Composer dist archives include only the necessary PHP files.

Recommended steps:

1. Prepare the repository

- Ensure composer.json is correct (package name, description, license, autoload). This repo already uses: keytd/dynamic-backend-client-php and PSR-4 autoload for KeyTD\\DynamicBackendClient\\ → php/.
- Optional but recommended: keep .gitattributes in place to export-ignore non-PHP assets (JS, tests, etc.).

2. Tag a release

- Commit any pending changes.
- Create a semantic version tag, e.g. v0.1.0: git tag v0.1.0 git push origin v0.1.0

3. Submit to Packagist

- Log in to  and click “Submit”.
- Paste the GitHub repository URL (this repo) and submit.
- Packagist will detect the package from the root composer.json and list versions based on your Git tags.

4. Enable auto-updates

- On the Packagist package page, enable GitHub auto-updates (if prompted) or add the Packagist GitHub hook from the Settings → Webhooks of your GitHub repo. This keeps Packagist in sync when you push new tags.

5. Usage after publish

- Consumers can install via Composer: composer require keytd/dynamic-backend-client-php

When would a separate repo be useful?

- If you want a lighter OSS footprint, isolated issue tracking, or different release cadence for PHP vs JS. In that case, you can move the php/ folder and composer.json into a new repository, keep the same package name (or choose a new one), and submit that repo to Packagist. This is optional — the monorepo approach works fine and is common.

🚀 Quick Start
-------------

[](#-quick-start)

### Basic Setup

[](#basic-setup)

```
import { ApiClient, BlogClient, TableClient } from '@keytd/dynamic-backend-client';

// Create the base API client
const apiClient = new ApiClient({
  baseUrl: 'https://your-api-url.com',
  schema: 'your_schema',
  timeout: 30000 // Optional, default is 30000ms
});

// Create specialized clients
const blogClient = new BlogClient(apiClient);
const tableClient = new TableClient(apiClient);
```

### Working with Blog Content

[](#working-with-blog-content)

```
// Fetch blog posts with pagination and filtering
async function fetchBlogPosts() {
  try {
    const posts = await blogClient.getPosts({
      page: 1,
      page_size: 10,
      status: 'published',
      include_tags: true,
      lang: 'en' // Optional language parameter
    });

    console.log('Total posts:', posts.pagination.total);
    console.log('Posts:', posts.data);
    return posts;
  } catch (error) {
    console.error('Error fetching posts:', error.message);
    // Handle error appropriately
  }
}

// Get a specific blog post by slug
async function getPostBySlug(slug) {
  try {
    const post = await blogClient.getPostBySlug(slug, {
      include_tags: true,
      include_comments: true
    });

    return post;
  } catch (error) {
    if (error.status === 404) {
      console.error('Post not found');
    } else {
      console.error(`Error: ${error.message}`);
    }
  }
}
```

### PHP Quick Start

[](#php-quick-start)

```
