Open-source project
mevdschee/php-crud-api avatar
mevdschee/php-crud-api

PHP-CRUD-API: A Single File REST API Over MySQL, PostgreSQL, SQL Server or SQLite

Single file PHP script that adds a REST API to a SQL database

3,737 stars1,027 forksPHPMIT

At a glance

What is it?
One api.php file turns an existing SQL schema into a TreeQL REST endpoint, with OpenAPI generation, GeoJSON, and an authentication layer. It is a good fit for internal tools and prototypes, and a poor fit for anything needing transactions or composite keys.
Who is it for?
Adopt PHP-CRUD-API when you have an existing SQL schema and want a read-and-write HTTP surface without writing controllers: internal dashboards, prototypes, admin panels, and data access for a front end that speaks JSON. Do not adopt it if your schema depends on composite primary keys, if you need multi-statement transactions, or if you need SQLite column alterations, because the README lists all three as unsupported.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 33 days ago.
What is it written in?
Mainly PHP, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What PHP-CRUD-API Replaces, and Who Ends Up Using It

Most teams that expose an existing database over HTTP write the same code four times: a router, a set of handlers per table, a serializer, and a permission check. PHP-CRUD-API skips all four by reading the schema at request time. Upload api.php, point it at a database, and every published table becomes a resource under /records/.

The audience is narrow but real. It fits engineers who already have a schema they cannot change, who need a JSON interface for a front end or an internal tool, and who do not want to maintain a framework for that purpose. The README describes the deployment as uploading the file and configuring it, and the repository ships a Dockerfile plus a docker-compose.yml, so both the shared-hosting path and the container path are covered.

It is explicitly the TreeQL reference implementation in PHP, which matters more than it sounds. TreeQL is a query convention where the URL path and query parameters encode traversal across related tables, so the API surface is derived from the schema rather than designed by hand. If you want a hand-designed resource model with custom verbs, this project is working against you.

How the Schema Becomes an Endpoint: Controllers, Middlewares and the Config Object

The configuration object at the bottom of api.php is the whole architecture in miniature. A single Config constructor takes driver, address, port, username, password and database, and the defaults are documented: driver defaults to mysql, address to localhost, and the port to whatever the driver considers standard. The README also lists a controllers key with a default of records,geojson,openapi,status, which tells you the request pipeline is a set of swappable controllers rather than hardcoded routes.

Middlewares are configured the same way, with cors as the default entry, and the project states it is PSR-4, PSR-7, PSR-12, PSR-15 and PSR-17 compliant. That is why the same code can be dropped into Laravel, Symfony or SlimPHP integrations, and why api.include.php exists for people who do not use Composer: it contains everything from api.php except the configuration from src/index.php, so it can be pulled in with PHP's include.

Two configuration keys are worth reading twice. tables takes a comma separated list and defaults to publishing all of them, which is convenient in development and dangerous in production if a table was never meant to be public. mapping lets you rename tables and columns in the API without touching the database, and the docker-compose.yml in the repository uses it to present abc_posts.abc_id as posts.id. The openApiFilterCount and openApiSubFilterCount keys control how many filter1 to filterN parameters appear in the generated specification, which is a sign that the OpenAPI output is generated from configuration rather than hand-written.

Installing PHP-CRUD-API and Making Your First Request

The README gives two installation paths. The first is to download api.php from the latest release, or directly from the raw URL on the main branch, upload it to a webserver, and edit the configuration at the bottom of the file. The requirements are PHP 7.2 or higher with PDO drivers enabled for one of MySQL, PostgreSQL, SQL Server or SQLite.

For local development the README suggests PHP's built-in server. Run this from the directory containing api.php, then open the records URL for a table in your database:

bash
php -S localhost:8080

The URL to test is http://localhost:8080/api.php/records/posts/1, which reads the row with id 1 from the posts table. If you see an error instead, the README notes that the configuration at the bottom of the file still has placeholder values, and that debug mode controls whether errors appear in X-Exception headers.

Configuration can also come from the environment, and the environment wins over the PHP config. The README documents the naming rule: capitals, a PHP_CRUD_API_ prefix, and underscores for word breaks.

bash
PHP_CRUD_API_DRIVER=mysql
PHP_CRUD_API_ADDRESS=localhost
PHP_CRUD_API_PORT=3306
PHP_CRUD_API_DATABASE=php-crud-api
PHP_CRUD_API_USERNAME=php-crud-api
PHP_CRUD_API_PASSWORD=php-crud-api
PHP_CRUD_API_DEBUG=1

The repository's docker-compose.yml wires exactly this pattern: a mysql:8.0 service named database, a webserver built from the included Dockerfile that publishes port 8080 to container port 80, and PHP_CRUD_API_ADDRESS set to database. The MySQL fixture at tests/fixtures/blog_mysql.sql is mounted into the container's init directory, so a compose up gives you a populated schema to query. That is the fastest way to see the API working without touching your own data.

The Limitations That Decide Your Architecture

The README has a limitations list, and it is honest enough to be useful. Primary keys must be either auto-increment in the range 1 to 2^53 or UUID. Composite primary and composite foreign keys are not supported. Transactions are not supported, which the README phrases as complex writes not being supported. Queries that call functions such as concat or sum are not supported. The database must define foreign key constraints, because relation detection depends on them.

The SQLite entry deserves attention: SQLite cannot have bigint auto-incrementing primary keys, and SQLite does not support altering table columns, so the structure-modification endpoint is partially unavailable there. Spatial features are also not supported on SQLite, while MySQL needs 5.7 or MariaDB 10.0 or higher for them, and PostgreSQL needs PostGIS 2.2 or higher.

The transaction gap is the one that changes designs. If your write path needs two tables updated atomically, the API will not give you that, and you either move that operation into a stored procedure or accept that the client owns the sequencing. The composite key restriction is similarly structural: a join table with a two-column primary key cannot be published as a resource. These are not bugs to be filed, they are the shape of the tool.

Where PHP-CRUD-API Sits Against Hand-Written Framework Code

The obvious alternative is not another single-file script but the framework you already run. A Laravel or Symfony application with an ORM gives you migrations, transactions, validation objects, and a resource layer you control. The difference in approach is where the schema lives. PHP-CRUD-API reads the live database and derives routes from it, so the database is the source of truth and the API follows. A framework project usually makes the code the source of truth and the database follows through migrations.

The trade-off shows up in two places. First, schema changes propagate instantly with PHP-CRUD-API and require a code change in a framework project, which is a win during prototyping and a risk in production where an accidental column rename silently changes the public API. Second, the configuration surface is small enough to read in one sitting, which is why the project can claim very little code that is easy to adapt. A framework gives you more control and more code to maintain.

Within the same niche, the repository points at sibling projects worth knowing: JS-CRUD-API is a JavaScript client for this API, PHP-API-AUTH is a single file authentication provider, and PHP-CRUD-UI is listed alongside them. There is also a filter generator that builds PHP-CRUD-API filter strings from expressions. If you adopt this project, those are the pieces that fill the gaps rather than a competing server.

Maintenance, Licensing and What an Upgrade Actually Costs

The repository is not archived, and the last push was on 2026-08-28, the same day as the v2.16.6 release. The three most recent releases, v2.16.4 through v2.16.6, all landed within two days of each other and are described as OpenAPI-related improvements, including OpenAPI filters and customOpenApiBuilders. That suggests the OpenAPI generation path is the active area of change, so if you depend on the generated specification, pin a version rather than tracking main.

The licence is MIT, which permits commercial use and modification. What that means in practice for a single-file deployment is that you can fork api.php, strip the controllers you do not want, and ship it inside a product. It does not remove the obligation to keep the copyright notice, and it does not make the project responsible for how you expose your data. The configuration default that publishes all tables is a good example of something the licence does not protect you from.

Upgrade cost is low by design. The README states this is a single file application, and the file is generated by build.php from the src/ directory, so an upgrade is replacing one file plus re-checking your configuration block. The risk is not the upgrade itself but the config drift: environment variables take precedence over the PHP configuration, so a container that sets PHP_CRUD_API_DRIVER will silently override whatever is written at the bottom of api.php. Check both places before concluding an upgrade changed behaviour.

Editorial conclusion

Adopt PHP-CRUD-API when you have an existing SQL schema and want a read-and-write HTTP surface without writing controllers: internal dashboards, prototypes, admin panels, and data access for a front end that speaks JSON. Do not adopt it if your schema depends on composite primary keys, if you need multi-statement transactions, or if you need SQLite column alterations, because the README lists all three as unsupported. Before committing, verify your primary key types against the auto-increment or UUID rule, confirm that foreign key constraints are actually declared in the database, and check which PDO driver your PHP build has enabled, since the driver list is fixed at mysql, pgsql, sqlsrv and sqlite.

Frequently asked questions

What is PHP-CRUD-API and what does it do?

It is a single file PHP script that adds a REST API to a MySQL, MariaDB, PostgreSQL, SQL Server or SQLite database. You upload api.php, configure the database connection, and the tables become REST resources. The README describes it as the TreeQL reference implementation in PHP.

How do I install PHP-CRUD-API?

Download api.php from the latest release or from the raw URL on the main branch, upload it to a webserver, and edit the configuration at the bottom of the file. For local development the README suggests running php -S localhost:8080 and opening http://localhost:8080/api.php/records/posts/1. The only requirement is PHP 7.2 or higher with PDO drivers enabled for your database.

Can PHP-CRUD-API run on SQLite?

Yes, SQLite 3.22 or higher is supported, but spatial features are not supported on SQLite. The README also notes that SQLite cannot have bigint typed auto-incrementing primary keys and does not support altering table columns.

Does PHP-CRUD-API support transactions?

No. The README lists complex writes and transactions as not supported, alongside composite primary and composite foreign keys and queries that call functions such as concat or sum. Any operation needing atomic multi-table writes has to be handled outside the API.

How do I configure PHP-CRUD-API with environment variables?

Write the config option in capitals with a PHP_CRUD_API_ prefix and underscores for word breaks, such as PHP_CRUD_API_DRIVER=mysql or PHP_CRUD_API_ADDRESS=localhost. The README states that environment variables take precedence over the PHP configuration. The repository's docker-compose.yml uses this to point the webserver at a database service.

Official sources

  1. Issues
  2. License: MIT
  3. mevdschee/php-crud-api on GitHub
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/mevdschee-php-crud-api.svg)](https://hysenlabs.com/projects/mevdschee-php-crud-api)