| Recommend this page to a friend! |
| Info | Reputation | Support forum | Blog | Links |
| Last Updated | Ratings | Unique User Downloads | Download Rankings | |||||
| 2025-11-10 (3 hours ago) | Not yet rated by the users | Total: Not yet counted | Not yet ranked | |||||
| Version | License | PHP version | Categories | |||
| php-crud-api-generat 1.4 | MIT/X Consortium ... | 8 | Databases, Libraries, Web services, P... |
| Description | Author | ||||||||
This package can create an API to access MySQL database record. |
|
Please read this document to learn how to create and configure a PHP REST API Web service to access MySQL database records.
Expose your MySQL/MariaDB database as a secure, flexible, and instant REST-like API. Features optional authentication (API key, Basic Auth, JWT, OAuth-ready), OpenAPI (Swagger) docs, and zero code generation.
? See detailed enhancement documentation ? ? Rate Limiting Documentation ? ? Request Logging Documentation ? ? Quick Start (5 minutes) ? ? Integration with upMVC Framework ? - NEW! Full-stack power combo ?? Comparison with PHP-CRUD-API v2 ? - NEW! Detailed feature comparison and when to use each ?? Feature Roadmap ? - NEW! Upcoming features and integrations
?? CRITICAL: The admin dashboard (dashboard.html) and health endpoint (health.php) expose sensitive information and MUST BE PROTECTED before deploying to production!
These files reveal: - API statistics, error rates, and performance metrics - Authentication failures and security threats - System information (memory, CPU, disk usage)
?? SECURE YOUR DASHBOARD NOW ? - Complete protection guide
Quick Fix (5 minutes): Add IP whitelist to .htaccess:
<Files "dashboard.html">
Order Deny,Allow
Deny from all
Allow from YOUR.IP.ADDRESS # Replace with your IP
</Files>
Just 4 simple steps:
# 1. Install via Composer
composer require bitshost/php-crud-api-generator
# 2. Copy 3 files to your project root
copy vendor/bitshost/php-crud-api-generator/public/index.php index.php
copy vendor/bitshost/php-crud-api-generator/dashboard.html dashboard.html
copy vendor/bitshost/php-crud-api-generator/health.php health.php
# 3. ? SECURE admin files (IMPORTANT!)
# Add this to .htaccess in your project root:
echo '<Files "dashboard.html">' >> .htaccess
echo ' Order Deny,Allow' >> .htaccess
echo ' Deny from all' >> .htaccess
echo ' Allow from 127.0.0.1' >> .htaccess
echo '</Files>' >> .htaccess
# 4. Edit index.php - Change 2 lines (point config paths to vendor)
# On line ~51, change:
# $dbConfig = require __DIR__ . '/../config/db.php';
# $apiConfig = require __DIR__ . '/../config/api.php';
# To:
# $dbConfig = require __DIR__ . '/vendor/bitshost/php-crud-api-generator/config/db.php';
# $apiConfig = require __DIR__ . '/vendor/bitshost/php-crud-api-generator/config/api.php';
# 5. Configure & run
notepad vendor/bitshost/php-crud-api-generator/config/db.php
notepad vendor/bitshost/php-crud-api-generator/config/api.php
php -S localhost:8000
That's it! Total modifications: 2 lines of code ?
? 5-Minute Quick Start Guide ? ? Secure Your Dashboard ? ? DO THIS BEFORE PRODUCTION!
Download complete ready-to-use project:
composer create-project bitshost/php-crud-api-generator my-api
cd my-api
# Configure
cp config/db.example.php config/db.php
cp config/api.example.php config/api.php
notepad config/db.php
notepad config/api.php
# Run
php -S localhost:8000
That's it! Everything in one folder, ready to run. 0 lines to modify ?
Edit config files in vendor directory:
notepad vendor/bitshost/php-crud-api-generator/config/db.php
notepad vendor/bitshost/php-crud-api-generator/config/api.php
Copy and edit config files:
cp config/db.example.php config/db.php
cp config/api.example.php config/api.php
Config file structure:
Edit config/db.php:
return [
'host' => 'localhost',
'dbname' => 'your_database',
'user' => 'your_db_user',
'pass' => 'your_db_password',
'charset' => 'utf8mb4'
];
Edit config/api.php:
return [
'auth_enabled' => false, // true to require authentication
'auth_method' => 'apikey', // 'apikey', 'basic', 'jwt', 'oauth'
'api_keys' => ['changeme123'], // API keys for 'apikey'
'basic_users' => ['admin' => 'secret'], // Users for 'basic' and 'jwt'
'jwt_secret' => 'YourSuperSecretKey',
'jwt_issuer' => 'yourdomain.com',
'jwt_audience' => 'yourdomain.com',
// Rate limiting (recommended for production)
'rate_limit' => [
'enabled' => true,
'max_requests' => 100, // 100 requests
'window_seconds' => 60, // per 60 seconds (1 minute)
],
// Request logging (recommended for production)
'logging' => [
'enabled' => true,
'log_dir' => __DIR__ . '/../logs',
'log_level' => 'info', // debug, info, warning, error
],
];
?? IMPORTANT: This framework ships with example credentials for development. You MUST change these before deploying to production!
# 1. Generate secure secrets (JWT secret + API keys)
php scripts/generate_secrets.php
# 2. Update config/api.php with generated secrets
# 3. Create admin user in database
php scripts/create_user.php admin [email protected] YourSecurePassword123! admin
? Full security guide: docs/AUTHENTICATION.md
Configure in config/api.php:
? Complete Authentication Guide ? - Detailed examples with Postman, HTTPie, cURL (JSON, Form Data, Multipart)
All requests go through public/index.php with action parameter.
| Action | Method | Usage Example |
|--------------|--------|-------------------------------------------------------------|
| tables | GET | /index.php?action=tables |
| columns | GET | /index.php?action=columns&table=users |
| list | GET | /index.php?action=list&table=users |
| count | GET | /index.php?action=count&table=users |
| read | GET | /index.php?action=read&table=users&id=1 |
| create | POST | /index.php?action=create&table=users (form POST or JSON) |
| update | POST | /index.php?action=update&table=users&id=1 (form POST or JSON) |
| delete | POST | /index.php?action=delete&table=users&id=1 |
| bulk_create | POST | /index.php?action=bulk_create&table=users (JSON array) |
| bulk_delete | POST | /index.php?action=bulk_delete&table=users (JSON with ids) |
| openapi | GET | /index.php?action=openapi |
| login | POST | /index.php?action=login (JWT only) |
curl Commands# List tables
curl http://localhost/index.php?action=tables
# List users with API key
curl -H "X-API-Key: changeme123" "http://localhost/index.php?action=list&table=users"
# JWT login
curl -X POST -d "username=admin&password=secret" http://localhost/index.php?action=login
# List with JWT token
curl -H "Authorization: Bearer <token>" "http://localhost/index.php?action=list&table=users"
# Basic auth
curl -u admin:secret "http://localhost/index.php?action=list&table=users"
# Bulk create
curl -X POST -H "Content-Type: application/json" \
-d '[{"name":"Alice","email":"[email protected]"},{"name":"Bob","email":"[email protected]"}]' \
"http://localhost/index.php?action=bulk_create&table=users"
# Bulk delete
curl -X POST -H "Content-Type: application/json" \
-d '{"ids":[1,2,3]}' \
"http://localhost/index.php?action=bulk_delete&table=users"
The API supports bulk operations for efficient handling of multiple records:
Create multiple records in a single transaction. If any record fails, the entire operation is rolled back.
Endpoint: POST /index.php?action=bulk_create&table=users
Request Body (JSON array):
[
{"name": "Alice", "email": "[email protected]", "age": 25},
{"name": "Bob", "email": "[email protected]", "age": 30},
{"name": "Charlie", "email": "[email protected]", "age": 35}
]
Response:
{
"success": true,
"created": 3,
"data": [
{"id": 1, "name": "Alice", "email": "[email protected]", "age": 25},
{"id": 2, "name": "Bob", "email": "[email protected]", "age": 30},
{"id": 3, "name": "Charlie", "email": "[email protected]", "age": 35}
]
}
Delete multiple records by their IDs in a single query.
Endpoint: POST /index.php?action=bulk_delete&table=users
Request Body (JSON):
{
"ids": [1, 2, 3, 4, 5]
}
Response:
{
"success": true,
"deleted": 5
}
Get the total count of records in a table with optional filtering. This is useful for analytics and doesn't include pagination overhead.
Endpoint: GET /index.php?action=count&table=users
Query Parameters:
- filter - (Optional) Same filter syntax as the list endpoint
Examples:
# Count all users
curl "http://localhost/index.php?action=count&table=users"
# Count active users
curl "http://localhost/index.php?action=count&table=users&filter=status:eq:active"
# Count users over 18
curl "http://localhost/index.php?action=count&table=users&filter=age:gt:18"
# Count with multiple filters
curl "http://localhost/index.php?action=count&table=users&filter=status:eq:active,age:gte:18"
Response:
{
"count": 42
}
The list action endpoint now supports advanced query parameters:
| Parameter | Type | Description |
|--------------|---------|---------------------------------------------------------------------------------------------------|
| filter | string | Filter rows by column values. Format: filter=col:op:value or filter=col:value (backward compatible). Use , to combine multiple filters. |
| sort | string | Sort by columns. Comma-separated. Use - prefix for DESC. Example: sort=-created_at,name |
| page | int | Page number (1-based). Default: 1 |
| page_size | int | Number of rows per page (max 100). Default: 20 |
| fields | string | Select specific fields. Comma-separated. Example: fields=id,name,email |
| Operator | Description | Example |
|----------|-------------|---------|
| eq or : | Equals | filter=name:eq:Alice or filter=name:Alice |
| neq or ne | Not equals | filter=status:neq:deleted |
| gt | Greater than | filter=age:gt:18 |
| gte or ge | Greater than or equal | filter=price:gte:100 |
| lt | Less than | filter=stock:lt:10 |
| lte or le | Less than or equal | filter=discount:lte:50 |
| like | Pattern match | filter=email:like:%@gmail.com |
| in | In list (pipe-separated) | filter=status:in:active|pending |
| notin or nin | Not in list | filter=role:notin:admin|super |
| null | Is NULL | filter=deleted_at:null: |
| notnull | Is NOT NULL | filter=email:notnull: |
Examples:
Response:
{
"data": [ ... array of rows ... ],
"meta": {
"total": 47,
"page": 2,
"page_size": 10,
"pages": 5
}
}
For /index.php?action=list&table={table}:
get:
summary: List rows in {table} with optional filtering, sorting, and pagination
parameters:
- name: table
in: query
required: true
schema: { type: string }
- name: filter
in: query
required: false
schema: { type: string }
description: |
Filter rows by column values. Example: filter=name:Alice,email:%gmail.com
- name: sort
in: query
required: false
schema: { type: string }
description: |
Sort by columns. Example: sort=-created_at,name
- name: page
in: query
required: false
schema: { type: integer, default: 1 }
description: Page number (1-based)
- name: page_size
in: query
required: false
schema: { type: integer, default: 20, maximum: 100 }
description: Number of rows per page (max 100)
responses:
'200':
description: List of rows with pagination meta
content:
application/json:
schema:
type: object
properties:
data:
type: array
items: { type: object }
meta:
type: object
properties:
total: { type: integer }
page: { type: integer }
page_size: { type: integer }
pages: { type: integer }
? Rate Limiting Documentation ? ? Request Logging Documentation ?
./vendor/bin/phpunit
Your API provides all the data you need - it's up to the client to decide how to combine it. This approach gives you maximum flexibility and control.
Current approach: Fetch related data in separate requests and combine on the client side.
// 1. Fetch user
const user = await fetch('/api.php?action=read&table=users&id=123')
.then(r => r.json());
// 2. Fetch user's posts
const posts = await fetch('/api.php?action=list&table=posts&filter=user_id:123')
.then(r => r.json());
// 3. Combine however you want
const userData = {
...user,
posts: posts.data
};
// Get multiple related records in one request
const postIds = '1|2|3|4|5'; // IDs from previous query
const comments = await fetch(
`/api.php?action=list&table=comments&filter=post_id:in:${postIds}`
).then(r => r.json());
// Group by post_id on client
const commentsByPost = comments.data.reduce((acc, comment) => {
acc[comment.post_id] = acc[comment.post_id] || [];
acc[comment.post_id].push(comment);
return acc;
}, {});
// Fetch multiple resources simultaneously
const [user, posts, comments] = await Promise.all([
fetch('/api.php?action=read&table=users&id=123').then(r => r.json()),
fetch('/api.php?action=list&table=posts&filter=user_id:123').then(r => r.json()),
fetch('/api.php?action=list&table=comments&filter=user_id:123').then(r => r.json())
]);
// All requests happen at once - much faster!
? See complete client-side join examples ?
Why this approach? - ? Client decides what data to fetch and when - ? Easy to optimize with caching and parallel requests - ? Different clients can have different data needs - ? Standard REST API practice - ? No server-side complexity for joins
Future: Auto-join/expand features may be added based on user demand.
MIT
Built by BitHost. PRs/issues welcome!
| File | Role | Description | ||
|---|---|---|---|---|
| Data | Auxiliary data | |||
| Data | Auxiliary data | |||
| Data | Auxiliary data | |||
| Data | Auxiliary data | |||
| Doc. | Documentation | |||
| Data | Auxiliary data | |||
| Example | Example script | |||
| Lic. | License text | |||
| Data | Auxiliary data | |||
| Data | Auxiliary data | |||
| Doc. | Documentation | |||
| Data | Auxiliary data | |||
| Data | Auxiliary data | |||
| / | config |
| File | Role | Description |
|---|---|---|
| |
Aux. | Configuration script |
| |
Aux. | Configuration script |
| |
Aux. | Configuration script |
| |
Aux. | Configuration script |
| / | docs |
| File | Role | Description |
|---|---|---|
| |
Example | Example script |
| |
Data | Auxiliary data |
| |
Class | Class source |
| |
Class | Class source |
| |
Data | Auxiliary data |
| |
Data | Auxiliary data |
| |
Class | Class source |
| |
Data | Auxiliary data |
| |
Data | Auxiliary data |
| |
Data | Auxiliary data |
| |
Data | Auxiliary data |
| |
Data | Auxiliary data |
| |
Data | Auxiliary data |
| |
Data | Auxiliary data |
| |
Aux. | Configuration script |
| |
Data | Auxiliary data |
| |
Data | Auxiliary data |
| |
Data | Auxiliary data |
| |
Data | Auxiliary data |
| |
Data | Auxiliary data |
| |
Example | Example script |
| |
Class | Class source |
| |
Data | Auxiliary data |
| |
Doc. | Documentation |
| |
Data | Auxiliary data |
| |
Data | Auxiliary data |
| |
Data | Auxiliary data |
| |
Class | Class source |
| / | examples |
| File | Role | Description |
|---|---|---|
| |
Aux. | Configuration script |
| |
Example | Example script |
| |
Example | Example script |
| |
Example | Example script |
| |
Example | Example script |
| / | scripts |
| File | Role | Description |
|---|---|---|
| |
Example | Example script |
| |
Aux. | Configuration script |
| |
Aux. | Configuration script |
| |
Example | Example script |
| / | src |
| File | Role | Description | ||
|---|---|---|---|---|
| |
Class | Class source | ||
| |
Class | Class source | ||
| |
Class | Class source | ||
| |
Class | Class source | ||
| |
Class | Class source | ||
| |
Class | Class source | ||
| |
Class | Class source | ||
| |
Class | Class source | ||
| |
Class | Class source | ||
| |
Class | Class source | ||
| |
Class | Class source | ||
| |
Class | Class source | ||
| |
Class | Class source | ||
| |
Class | Class source | ||
| / | src | / | Cache |
| File | Role | Description | ||
|---|---|---|---|---|
| |
Class | Class source | ||
| |
Class | Class source | ||
| / | src | / | Config |
| File | Role | Description |
|---|---|---|
| |
Class | Class source |
| |
Class | Class source |
| / | tests |
| File | Role | Description |
|---|---|---|
| |
Class | Class source |
| |
Class | Class source |
| |
Example | Example script |
| |
Example | Example script |
| |
Example | Example script |
| |
Example | Example script |
| |
Example | Example script |
| |
Example | Example script |
| |
Class | Class source |
| |
Class | Class source |
| |
Example | Example script |
| The PHP Classes site has supported package installation using the Composer tool since 2013, as you may verify by reading this instructions page. |
| Version Control | Unique User Downloads | |||||||
| 100% |
|
| Applications that use this package |
If you know an application of this package, send a message to the author to add a link here.