### Install Dependencies Source: https://github.com/mevdschee/php-crud-api/blob/main/README.md Use this command to install all project dependencies via Composer. ```bash php install.php ``` -------------------------------- ### Install Memcached Dependencies Source: https://github.com/mevdschee/php-crud-api/blob/main/README.md Install the necessary PHP extensions and Memcached server for the Memcached cache engine. ```bash sudo apt install php-memcached memcached ``` -------------------------------- ### Docker Compose Installation and Execution Source: https://github.com/mevdschee/php-crud-api/blob/main/README.md Commands to install Docker Compose, build the Docker image, and run the application with a MySQL database and Apache webserver. Test the running application via the specified URL. ```bash sudo apt install docker-compose docker-compose build docker-compose up ``` -------------------------------- ### Docker Installation Commands Source: https://github.com/mevdschee/php-crud-api/blob/main/README.md Commands to install Docker and Docker Buildx on Debian-based systems. After installation, log out and log back in for changes to take effect. ```bash sudo apt install docker.io docker-buildx sudo usermod -aG docker ${USER} ``` -------------------------------- ### Install Memcache Dependencies Source: https://github.com/mevdschee/php-crud-api/blob/main/README.md Install the necessary PHP extensions and Memcached server for the Memcache cache engine. ```bash sudo apt install php-memcache memcached ``` -------------------------------- ### Custom Controller Example Source: https://github.com/mevdschee/php-crud-api/blob/main/README.md Example of how to create and register a custom controller to add new REST API endpoints. ```APIDOC ## Custom Controller Registration ### Description Allows users to add their own custom REST API endpoints by creating a custom controller class and registering it in the configuration. ### Example Controller Class ```php use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; use Tqdev\PhpCrudApi\Cache\Cache; use Tqdev\PhpCrudApi\Column\ReflectionService; use Tqdev\PhpCrudApi\Controller\Responder; use Tqdev\PhpCrudApi\Database\GenericDB; use Tqdev\PhpCrudApi\Middleware\Router\Router; class MyHelloController { private $responder; public function __construct(Router $router, Responder $responder, GenericDB $db, ReflectionService $reflection, Cache $cache) { $router->register('GET', '/hello', array($this, 'getHello')); $this->responder = $responder; } public function getHello(ServerRequestInterface $request): ResponseInterface { return $this->responder->success(['message' => "Hello World!"]); } } ``` ### Configuration Register the custom controller in the `Config` object: ```php $config = new Config([ ... 'customControllers' => 'MyHelloController', ... ]); ``` The `customControllers` configuration option supports a comma-separated list of controller class names. ``` -------------------------------- ### Database Configuration Example Source: https://github.com/mevdschee/php-crud-api/blob/main/README.md Configure the API to connect to your database by editing these lines in 'api.php'. Replace 'xxx' with your actual credentials. ```php $config = new Config([ 'username' => 'xxx', 'password' => 'xxx', 'database' => 'xxx', ]); ``` -------------------------------- ### Install Redis Cache Dependencies Source: https://github.com/mevdschee/php-crud-api/blob/main/README.md Install the necessary PHP extensions and Redis server for the Redis cache engine. ```bash sudo apt install php-redis redis ``` -------------------------------- ### Basic Authentication Header Example Source: https://github.com/mevdschee/php-crud-api/blob/main/README.md An example of the 'Authorization' header for Basic authentication. It requires a base64 url encoded username and password separated by a colon. ```text Authorization: Basic dXNlcm5hbWUxOnBhc3N3b3JkMQ ``` -------------------------------- ### Registering Custom Controllers in Config Source: https://github.com/mevdschee/php-crud-api/blob/main/README.md Configuration example showing how to register custom controller classes in the 'customControllers' setting. ```php $config = new Config([ ... 'customControllers' => 'MyHelloController', ... ]); ``` -------------------------------- ### Vue.js CRUD Application Setup Source: https://github.com/mevdschee/php-crud-api/blob/main/examples/clients/vue.html Initializes the Vue.js application, sets up Axios for API requests, and defines the main Vue instance with routing. ```javascript var posts = null; var api = axios.create({baseURL: '/api.php/records'}); function findpost (postId) { return posts[findpostKey(postId)]; }; function findpostKey (postId) { for (var key = 0; key < posts.length; key++) { if (posts[key].id == postId) { return key; } } }; var List = Vue.extend({ template: '#post-list', data: function () { return {posts: posts, searchKey: ''}; }, created: function () { var self = this; api.get('/posts').then(function (response) { posts = self.posts = response.data.records; }).catch(function (error) { console.log(error); }); }, computed: { filteredposts: function () { return this.posts.filter(function (post) { return this.searchKey=='' || post.content.indexOf(this.searchKey) !== -1; },this); } } }); var post = Vue.extend({ template: '#post', data: function () { return {post: findpost(this.$route.params.post_id)}; } }); var postEdit = Vue.extend({ template: '#post-edit', data: function () { return {post: findpost(this.$route.params.post_id)}; }, methods: { updatepost: function () { var post = this.post; api.put('/posts/'+post.id,post).then(function (response) { console.log(response.data); }).catch(function (error) { console.log(error); }); router.push('/'); } } }); var postDelete = Vue.extend({ template: '#post-delete', data: function () { return {post: findpost(this.$route.params.post_id)}; }, methods: { deletepost: function () { var post = this.post; api.delete('/posts/'+post.id).then(function (response) { console.log(response.data); }).catch(function (error) { console.log(error); }); router.push('/'); } } }); var Addpost = Vue.extend({ template: '#add-post', data: function () { return {post: {content: '', user_id: 1, category_id: 1}} }, methods: { createpost: function() { var post = this.post; api.post('/posts',post).then(function (response) { post.id = response.data; }).catch(function (error) { console.log(error); }); router.push('/'); } } }); var router = new VueRouter({ routes:[ { path: '/', component: List}, { path: '/post/:post_id', component: post, name: 'post'}, { path: '/add-post', component: Addpost}, { path: '/post/:post_id/edit', component: postEdit, name: 'post-edit'}, { path: '/post/:post_id/delete', component: postDelete, name: 'post-delete'} ] }); app = new Vue({ router:router }).$mount('#app') ``` -------------------------------- ### Filtering Examples Source: https://github.com/mevdschee/php-crud-api/blob/main/README.md Demonstrates various filtering options for list calls, including different match types and multiple filters. ```APIDOC ## Filtering Examples ### Description Provides examples of how to use the 'filter' query parameter for various matching conditions and multiple filters. ### Query Parameters - **filter** (string) - Optional - Used for filtering records. Format: column,match_type,value. Supported match types: cs, sw, ew, eq, lt, le, ge, gt, bt, in, is. Can be negated with 'n' prefix (e.g., 'neq'). ### Examples - **Equal filter:** `GET /records/categories?filter=name,eq,Internet` - **Starts with filter:** `GET /records/categories?filter=name,sw,Inter` - **Lower than or equal filter:** `GET /records/categories?filter=id,le,1` - **Not greater than filter:** `GET /records/categories?filter=id,ngt,1` - **Between filter:** `GET /records/categories?filter=id,bt,0,1` - **In filter:** `GET /records/categories?filter=id,in,0,1` ### Multiple Filters (AND) `GET /records/categories?filter=id,gt,1&filter=id,lt,3` ### Multiple Filters (OR) `GET /records/categories?filter1=id,eq,2&filter2=id,eq,4` ### Response Example (for filter calls) { "records": [ { "id": 1, "name": "Internet" } ] } ``` -------------------------------- ### Docker Test Execution Script Source: https://github.com/mevdschee/php-crud-api/blob/main/README.md Example output from running build_all.sh and run_all.sh in the docker directory. This demonstrates test results across different Debian and PHP versions. ```text ================================================ Debian 11 (PHP 7.4) ================================================ [1/4] Starting MariaDB 10.5 ..... done [2/4] Starting PostgreSQL 13.4 .. done [3/4] Starting SQLServer 2017 ... skipped [4/4] Cloning PHP-CRUD-API v2 ... skipped ------------------------------------------------ mysql: 121 tests ran in 1018 ms, 1 skipped, 0 failed pgsql: 121 tests ran in 740 ms, 1 skipped, 0 failed sqlsrv: skipped, driver not loaded sqlite: 121 tests ran in 691 ms, 13 skipped, 0 failed ================================================ Debian 12 (PHP 8.2) ================================================ [1/4] Starting MariaDB 10.11 .... done [2/4] Starting PostgreSQL 15.3 .. done [3/4] Starting SQLServer 2019 ... skipped [4/4] Cloning PHP-CRUD-API v2 ... skipped ------------------------------------------------ mysql: 121 tests ran in 979 ms, 1 skipped, 0 failed pgsql: 121 tests ran in 753 ms, 1 skipped, 0 failed sqlsrv: skipped, driver not loaded sqlite: 121 tests ran in 700 ms, 13 skipped, 0 failed ================================================ Debian 13 (PHP 8.4) ================================================ [1/4] Starting MariaDB 11.8 .... done [2/4] Starting PostgreSQL 17 .... done [3/4] Starting SQLServer 2025 ... done [4/4] Cloning PHP-CRUD-API v2 ... skipped ------------------------------------------------ mysql: 121 tests ran in 1649 ms, 1 skipped, 0 failed pgsql: 121 tests ran in 1398 ms, 1 skipped, 0 failed sqlsrv: 121 tests ran in 23722 ms, 1 skipped, 0 failed sqlite: 121 tests ran in 1340 ms, 13 skipped, 0 failed ``` -------------------------------- ### Filter Records by Name (Starts With) Source: https://github.com/mevdschee/php-crud-api/blob/main/README.md Use the 'sw' match type in the 'filter' parameter to find records where the name starts with a specific string. This example finds names starting with 'Inter'. ```http GET /records/categories?filter=name,sw,Inter ``` -------------------------------- ### JWT Authentication Header Example Source: https://github.com/mevdschee/php-crud-api/blob/main/README.md An example of the 'X-Authorization' header for JWT authentication. It requires a base64 url encoded and dot separated token header, body, and signature after 'Bearer'. ```text X-Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlhdCI6IjE1MzgyMDc2MDUiLCJleHAiOjE1MzgyMDc2MzV9.Z5px_GT15TRKhJCTHhDt5Z6K6LRDSFnLj8U5ok9l7gw ``` -------------------------------- ### Custom Controller Example Source: https://github.com/mevdschee/php-crud-api/blob/main/README.md An example of a custom controller class that can be registered with the PHP-CRUD-API to add custom REST API endpoints. ```php use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; use Tqdev\PhpCrudApi\Cache\Cache; use Tqdev\PhpCrudApi\Column\ReflectionService; use Tqdev\PhpCrudApi\Controller\Responder; use Tqdev\PhpCrudApi\Database\GenericDB; use Tqdev\PhpCrudApi\Middleware\Router\Router; class MyHelloController { private $responder; public function __construct(Router $router, Responder $responder, GenericDB $db, ReflectionService $reflection, Cache $cache) { $router->register('GET', '/hello', array($this, 'getHello')); $this->responder = $responder; } public function getHello(ServerRequestInterface $request): ResponseInterface { return $this->responder->success(['message' => "Hello World!"]); } } ``` -------------------------------- ### Customization Handlers for Request/Response Source: https://github.com/mevdschee/php-crud-api/blob/main/README.md Implement custom logic before or after request handlers using the 'customization' middleware. This example adds an 'X-Time-Taken' header to the response. ```php 'customization.beforeHandler' => function ($operation, $tableName, $request, $environment) { $environment->start = microtime(true); }, 'customization.afterHandler' => function ($operation, $tableName, $response, $environment) { return $response->withHeader('X-Time-Taken', microtime(true) - $environment->start); } ``` -------------------------------- ### Local Development Server Source: https://github.com/mevdschee/php-crud-api/blob/main/README.md Run PHP's built-in web server for local development. This command starts a server on localhost port 8080. ```bash php -S localhost:8080 ``` -------------------------------- ### Environment Variable Configuration Source: https://github.com/mevdschee/php-crud-api/blob/main/README.md Configure the API using environment variables. These variables take precedence over the PHP configuration. Example for MySQL connection. ```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 ``` -------------------------------- ### JWT Claims Example Source: https://github.com/mevdschee/php-crud-api/blob/main/README.md An example of the JSON claims that can be included in a JWT token. These claims are signed and verified by an authentication server. ```json { "sub": "1234567890", "name": "John Doe", "admin": true, "iat": "1538207605", "exp": 1538207635 } ``` -------------------------------- ### GET Request with Joins Source: https://github.com/mevdschee/php-crud-api/blob/main/README.md Use the 'join' parameter in the URL to specify multiple join paths. Intermediate tables for hasAndBelongsToMany relationships can be omitted. ```http GET /records/posts?join=comments,users&join=tags ``` -------------------------------- ### Angular POST and GET Request Source: https://github.com/mevdschee/php-crud-api/blob/main/examples/clients/angular.html This snippet shows how to send a POST request to create a new record and then immediately make a GET request to refresh the list of records using Angular's $http service. Ensure the API endpoint is correctly configured. ```javascript var app = angular.module('myApplication', []); app.controller('postController', function($scope, $http) { var url = '/api.php/records/posts'; $http.post(url, {user_id: 1, category_id: 1, content: "from angular"}).success(function() { $http.get(url).success(function(response) { $scope.posts = response.records; }); }); }); ``` -------------------------------- ### Wordpress Authentication Routes Source: https://github.com/mevdschee/php-crud-api/blob/main/README.md Defines the routes for Wordpress authentication, including getting the current user, logging in, and logging out. Requires 'wpAuth.wpDirectory' configuration. ```text method path - parameters - description --------------------------------------------------------------------------------------------------- GET /me - - returns the user that is currently logged in POST /login - username, password - logs a user in by username and password POST /logout - - logs out the currently logged in user ``` -------------------------------- ### Map Table and Column Names Source: https://github.com/mevdschee/php-crud-api/blob/main/README.md Use the 'mapping' configuration to rename tables and columns. This example shows how to map 'wp_posts' to 'posts' and 'wp_posts.ID' to 'posts.id'. ```php 'mapping' => 'wp_posts=posts,wp_posts.ID=posts.id' ``` -------------------------------- ### Configure Multi-tenancy Handler for Single Database Source: https://github.com/mevdschee/php-crud-api/blob/main/README.md Define a handler for the 'multiTenancy' middleware to filter operations based on a 'customer_id'. This example sets the 'customer_id' to 12 for all operations except 'create', where it also sets the column. ```php 'multiTenancy.handler' => function ($operation, $tableName) { return ['customer_id' => 12]; }, ``` -------------------------------- ### Configure Reconnect Middleware for Tenant-Specific Database Source: https://github.com/mevdschee/php-crud-api/blob/main/README.md Specify a handler for the 'reconnect' middleware to dynamically select the database name based on the tenant. This example directs the API to connect to 'customer_12'. ```php 'reconnect.databaseHandler' => function () { return 'customer_12'; }, ``` -------------------------------- ### List Records Source: https://github.com/mevdschee/php-crud-api/blob/main/README.md Use a GET request to /records/posts to retrieve a list of records. The response contains a 'records' array with the matching entries. ```http GET /records/posts ``` ```json { "records":[ { "id": 1, "title": "Hello world!", "content": "Welcome to the first post.", "created": "2018-03-05T20:12:56Z" } ] } ``` -------------------------------- ### Restrict Access to a Table Source: https://github.com/mevdschee/php-crud-api/blob/main/README.md Use the 'authorization.tableHandler' to prevent access to specific tables for all operations. This example blocks access to the 'license_keys' table. ```php 'authorization.tableHandler' => function ($operation, $tableName) { return $tableName != 'license_keys'; }, ``` -------------------------------- ### JSON Encoding Options Configuration Source: https://github.com/mevdschee/php-crud-api/blob/main/README.md Configure JSON encoding behavior by setting the 'jsonOptions' parameter. This example combines multiple standard PHP JSON constants. ```php 'jsonOptions' => JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES ``` -------------------------------- ### Initialize DataTable with AJAX Source: https://github.com/mevdschee/php-crud-api/blob/main/examples/clients/datatables.html Initializes a DataTables instance on an HTML element with the ID 'example'. It configures the table to fetch data from a specified API endpoint using AJAX and defines how the data should be mapped to table columns. ```javascript $(document).ready(function() { $('#example').DataTable( { ajax: { url: '/api.php/records/posts?join=categories&join=users', dataSrc: 'records' }, columns: [ { data: "id" }, { data: "user_id.username" }, { data: "category_id.name" }, { data: "content" } ] }); }); ``` -------------------------------- ### Database Authentication - Get Current User Source: https://github.com/mevdschee/php-crud-api/blob/main/README.md Returns the user that is currently logged in. ```APIDOC ## Database Authentication - Get Current User ### Description Returns the user that is currently logged in. ### Method GET ### Endpoint /me ### Parameters - No parameters are required for this endpoint. ### Request Example ``` GET /me Host: example.com ``` ### Response #### Success Response (200) - Returns the details of the currently logged-in user. #### Response Example ```json { "data": [ { "id": 1, "username": "testuser" } ] } ``` ``` -------------------------------- ### Multiple Filters (AND) Source: https://github.com/mevdschee/php-crud-api/blob/main/README.md Apply multiple filters using the 'filter' parameter to combine conditions with an AND logic. This example requests categories where id > 1 AND id < 3. ```http GET /records/categories?filter=id,gt,1&filter=id,lt,3 ``` -------------------------------- ### Example JSON Response with Joins Source: https://github.com/mevdschee/php-crud-api/blob/main/README.md This JSON illustrates how the API returns joined data, resolving 'belongsTo' relationships by replacing foreign keys with objects and nesting 'hasMany'/'hasAndBelongsToMany' relationships under table-named properties. ```json { "records":[ { "id": 1, "title": "Hello world!", "content": "Welcome to the first post.", "created": "2018-03-05T20:12:56Z", "comments": [ { "id": 1, "post_id": 1, "user_id": { "id": 1, "username": "mevdschee", "phone": null }, "message": "Hi!" }, { "id": 2, "post_id": 1, "user_id": { "id": 1, "username": "mevdschee", "phone": null }, "message": "Hi again!" } ], "tags": [] }, { "id": 2, "title": "Black is the new red", "content": "This is the second post.", "created": "2018-03-06T21:34:01Z", "comments": [], "tags": [ { "id": 1, "message": "Funny" }, { "id": 2, "message": "Informational" } ] } ] } ``` -------------------------------- ### Filter Records by Condition Source: https://github.com/mevdschee/php-crud-api/blob/main/README.md Implement 'authorization.recordHandler' to add filters to queries, restricting which records can be accessed. This example filters out records where the username is 'admin' for the 'users' table. ```php 'authorization.recordHandler' => function ($operation, $tableName) { return ($tableName == 'users') ? 'filter=username,neq,admin' : ''; }, ``` -------------------------------- ### Initialize Leaflet Map and Add Tile Layers Source: https://github.com/mevdschee/php-crud-api/blob/main/examples/clients/leaflet/vanilla.html Initializes a Leaflet map centered on specific coordinates and zoom level, then adds a world topo map tile layer. This is a common setup for displaying geographical data. ```javascript var mymap = L.map('mapid').setView([20, 30], 3); L.tileLayer('https://services.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer/tile/{z}/{y}/{x}', { maxZoom: 18, }).addTo(mymap); ``` -------------------------------- ### Filter Records by Name (Equal) Source: https://github.com/mevdschee/php-crud-api/blob/main/README.md Apply a filter to list calls using the 'filter' parameter. This example filters categories where the name is exactly 'Internet'. ```http GET /records/categories?filter=name,eq,Internet ``` ```json { "records":[ { "id": 1, "name": "Internet" } ] } ``` -------------------------------- ### Nginx Server Block Configuration Source: https://github.com/mevdschee/php-crud-api/blob/main/README.md Configuration for serving the API under Nginx with PHP-FPM. This setup includes listening on port 80 and handling PHP requests. ```nginx server { listen 80 default_server; listen [::]:80 default_server; root /var/www/html; index index.php index.html index.htm index.nginx-debian.html; server_name server_domain_or_IP; location / { try_files $uri $uri/ /api.php?$args; } location ~ [^/]\.php(/|$) { fastcgi_split_path_info ^(.+\.php)(/.+); try_files $fastcgi_script_name =404; set $path_info $fastcgi_path_info; fastcgi_param PATH_INFO $path_info; fastcgi_index index.php; include fastcgi.conf; fastcgi_pass unix:/run/php/php7.0-fpm.sock; } location ~ /\.ht { deny all; } } ``` -------------------------------- ### Example of Input Validation Failure Response Source: https://github.com/mevdschee/php-crud-api/blob/main/README.md Illustrates the server's response when input validation fails, providing a structured error message that can be used for user feedback. ```json { "code": 1013, "message": "Input validation failed for 'comments'", "details": { "post_id":"must be numeric" } } ``` -------------------------------- ### Configure Type Sanitation for Specific Fields Source: https://github.com/mevdschee/php-crud-api/blob/main/README.md Specify which data types and tables should undergo type sanitation using 'sanitation.types' and 'sanitation.tables'. This example enables sanitation for date and timestamp fields in 'posts' and 'comments' tables. ```php 'sanitation.types' => 'date,timestamp', 'sanitation.tables' => 'posts,comments', ``` -------------------------------- ### Read a Specific Record Source: https://github.com/mevdschee/php-crud-api/blob/main/README.md Use a GET request to /records/posts/{id} to retrieve a specific record by its primary key. The response will be the JSON representation of the record. ```http GET /records/posts/1 ``` ```json { "id": 1, "title": "Hello world!", "content": "Welcome to the first post.", "created": "2018-03-05T20:12:56Z" } ``` -------------------------------- ### Multiple Filters (OR) Source: https://github.com/mevdschee/php-crud-api/blob/main/README.md Use numbered filter parameters (e.g., filter1, filter2) to combine conditions with an OR logic. This example requests categories where id = 2 OR id = 4. ```http GET /records/categories?filter1=id,eq,2&filter2=id,eq,4 ``` -------------------------------- ### Search Text Fields with textSearch Middleware Source: https://github.com/mevdschee/php-crud-api/blob/main/README.md Use the 'textSearch' middleware to perform wildcard text searches on text fields when listing records. Specify a 'search' parameter in the GET request. ```http GET /records/posts?search=Hello ``` -------------------------------- ### Compile Project Files Source: https://github.com/mevdschee/php-crud-api/blob/main/README.md Compile all project files into a single 'api.php' file for deployment. ```bash php build.php ``` -------------------------------- ### Running Functional Tests Source: https://github.com/mevdschee/php-crud-api/blob/main/README.md Commands to execute the functional tests locally. These commands build the project and then run the tests. ```bash php build.php php test.php ``` -------------------------------- ### Disable a Specific Route Source: https://github.com/mevdschee/php-crud-api/blob/main/README.md Use 'authorization.pathHandler' to disable access to specific API routes. This example disables the '/openapi' route. ```php 'authorization.pathHandler' => function ($path) { return $path === 'openapi' ? false : true; }, ``` -------------------------------- ### Initialize Firebase and FirebaseUI Source: https://github.com/mevdschee/php-crud-api/blob/main/examples/clients/firebase/vanilla.html Configure your Firebase project and initialize the FirebaseUI widget with your desired sign-in providers. This snippet sets up Google, Facebook, Twitter, GitHub, Email, Phone, and Anonymous authentication. ```javascript var firebaseConfig = { apiKey: "", authDomain: "", databaseURL: "", projectId: "", storageBucket: "", messagingSenderId: "", appId: "" }; firebase.initializeApp(firebaseConfig); var uiConfig = { signInSuccessUrl: './vanilla-success.html', signInOptions: [ firebase.auth.GoogleAuthProvider.PROVIDER_ID, firebase.auth.FacebookAuthProvider.PROVIDER_ID, firebase.auth.TwitterAuthProvider.PROVIDER_ID, firebase.auth.GithubAuthProvider.PROVIDER_ID, firebase.auth.EmailAuthProvider.PROVIDER_ID, firebase.auth.PhoneAuthProvider.PROVIDER_ID, firebaseui.auth.AnonymousAuthProvider.PROVIDER_ID ], tosUrl: '', privacyPolicyUrl: function() { window.location.assign(''); } }; var ui = new firebaseui.auth.AuthUI(firebase.auth()); ui.start('#firebaseui-auth-container', uiConfig); ``` -------------------------------- ### Interactive Docker Environment Script Source: https://github.com/mevdschee/php-crud-api/blob/main/README.md Use the './run.sh' script to enter an interactive prompt within a chosen Docker environment. This allows for easy debugging as local files are mounted. ```bash $ ./run.sh 1) debian11 2) debian12 3) debian13 > 3 ================================================ Debian 13 (PHP 8.4) ================================================ [1/4] Starting MariaDB 11.8 .... done [2/4] Starting PostgreSQL 17 .... done [3/4] Starting SQLServer 2025 ... done [4/4] Cloning PHP-CRUD-API v2 ... skipped ------------------------------------------------ mysql: 121 tests ran in 1649 ms, 1 skipped, 0 failed pgsql: 121 tests ran in 1398 ms, 1 skipped, 0 failed sqlsrv: 121 tests ran in 23722 ms, 1 skipped, 0 failed sqlite: 121 tests ran in 1340 ms, 13 skipped, 0 failed root@b7ab9472e08f:/php-crud-api# ``` -------------------------------- ### Firebase Initialization and Auth State Listener Source: https://github.com/mevdschee/php-crud-api/blob/main/examples/clients/firebase/vanilla-success.html Initializes Firebase with provided configuration and sets up a listener for authentication state changes. This is crucial for managing user sessions and securing API calls. ```javascript var firebaseConfig = { apiKey: "", authDomain: "", databaseURL: "", projectId: "", storageBucket: "", messagingSenderId: "", appId: "" }; firebase.initializeApp(firebaseConfig); function requestAPI(accessToken) { var req = new XMLHttpRequest(); req.onreadystatechange = function () { if (req.readyState == 4) { try { document.getElementById('output').innerHTML = JSON.stringify(JSON.parse(req.responseText), undefined, 4); } catch (error) { document.getElementById('output').innerHTML = req.responseText; } } } req.open("GET", url, true); req.setRequestHeader('X-Authorization', 'Bearer ' + accessToken); req.send(); } function initApp() { firebase.auth().onAuthStateChanged(function (user) { if (user) { var displayName = user.displayName; var email = user.email; var emailVerified = user.emailVerified; var photoURL = user.photoURL; var uid = user.uid; var phoneNumber = user.phoneNumber; var providerData = user.providerData; user.getIdToken().then(function (accessToken) { document.getElementById('sign-in-status').textContent = 'Signed in'; document.getElementById('account-details').textContent = JSON.stringify({ displayName: displayName, email: email, emailVerified: emailVerified, phoneNumber: phoneNumber, photoURL: photoURL, uid: uid, accessToken: accessToken, providerData: providerData }, undefined, 4); requestAPI(accessToken) }); } else { document.getElementById('sign-in-status').textContent = 'Signed out'; document.getElementById('account-details').textContent = 'null'; } }, function (error) { console.log(error); }); }; window.addEventListener('load', initApp); ``` -------------------------------- ### Database Authentication - Register Source: https://github.com/mevdschee/php-crud-api/blob/main/README.md Adds a new user with the provided username and password to the system. This functionality must be enabled via configuration. ```APIDOC ## Database Authentication - Register ### Description Adds a new user with the provided username and password to the system. This functionality must be enabled via configuration. ### Method POST ### Endpoint /register ### Parameters #### Request Body - **username** (string) - Required - The username for the new user. - **password** (string) - Required - The password for the new user. ### Request Example ```json { "username": "newuser", "password": "securepassword" } ``` ### Response #### Success Response (200) - Typically returns the newly created user's data or a success message. #### Response Example ```json { "data": [ { "id": 2, "username": "newuser" } ] } ``` ``` -------------------------------- ### Basic Authentication Source: https://github.com/mevdschee/php-crud-api/blob/main/README.md Supports authentication using a .htpasswd file and Basic Authorization header. ```APIDOC ## Basic Authentication ### Description Authenticates users via a file (default: .htpasswd) containing usernames and hashed passwords. The authenticated username is stored in `$_SESSION['username']`. Requires an 'Authorization' header with a base64 encoded 'username:password' string. ### Method GET (Implicit, typically used with requests requiring authentication) ### Endpoint (Applies to all endpoints requiring basic authentication) ### Parameters #### Request Headers - **Authorization** (string) - Required - Base64 URL encoded string of 'username:password', prefixed with 'Basic '. Example: `Authorization: Basic dXNlcm5hbWUxOnBhc3N3b3JkMQ` ``` -------------------------------- ### Configure Database Connection Credentials Source: https://github.com/mevdschee/php-crud-api/blob/main/README.md Use 'reconnect.usernameHandler' and 'reconnect.passwordHandler' to dynamically provide database connection credentials, often retrieved from session data. ```php 'reconnect.usernameHandler' => function () { return 'mevdschee'; }, 'reconnect.passwordHandler' => function () { return 'secret123'; }, ``` -------------------------------- ### Restrict Access to a Column Source: https://github.com/mevdschee/php-crud-api/blob/main/README.md Use the 'authorization.columnHandler' to restrict access to specific columns within a table. This example prevents access to the 'password' column in the 'users' table. ```php 'authorization.columnHandler' => function ($operation, $tableName, $columnName) { return !($tableName == 'users' && $columnName == 'password'); }, ``` -------------------------------- ### Apache .htaccess Configuration Source: https://github.com/mevdschee/php-crud-api/blob/main/README.md Enable mod_rewrite and add this to your .htaccess file for Apache. Ensure the .htaccess file is in the same directory as api.php. ```apache RewriteEngine On RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^(.*)$ api.php/$1 [L,QSA] ``` -------------------------------- ### Testing API Endpoint Source: https://github.com/mevdschee/php-crud-api/blob/main/README.md Access a specific record from the 'posts' table via the API. Ensure the API script is running and accessible. ```bash http://localhost:8080/api.php/records/posts/1 ``` -------------------------------- ### Filter Records by ID (Between) Source: https://github.com/mevdschee/php-crud-api/blob/main/README.md Use the 'bt' match type to filter records where a numeric field falls within a range. This example filters IDs between 0 and 1 (inclusive). ```http GET /records/categories?filter=id,bt,0,1 ``` -------------------------------- ### Filter Records by ID (Not Greater Than) Source: https://github.com/mevdschee/php-crud-api/blob/main/README.md Use the 'ngt' match type to filter records where a numeric field is not greater than a specified value. This example filters IDs that are not greater than 1. ```http GET /records/categories?filter=id,ngt,1 ``` -------------------------------- ### Vanilla JavaScript File Upload and Listing Source: https://github.com/mevdschee/php-crud-api/blob/main/examples/clients/upload/vanilla.html This snippet handles image preview, upload, and listing using XMLHttpRequest. Ensure your browser supports the HTML5 File API. ```javascript if (!window.File || !window.FileReader || !window.FileList || !window.Blob) { alert("Your browser is too old to support HTML5 File API"); } function showImagePreview() { var demoImage = document.querySelector('img#preview'); var file = document.querySelector('input[type=file]').files[0]; var reader = new FileReader(); reader.onload = function (event) { console.log(reader.result) demoImage.src = reader.result; } console.log(file) reader.readAsDataURL(file); } function uploadImageFile() { var demoImage = document.querySelector('img#preview'); var req = new XMLHttpRequest(); req.onreadystatechange = function () { if (req.readyState==4) { console.log(req.responseText); listImageFiles(); } } url = '/api.php/records/categories'; req.open("POST", url); var icon = demoImage.src.split(";")[1].split(",")[1]; req.send(JSON.stringify({"name":"upload","icon":icon})); } function listImageFiles() { var ul = document.querySelector('ul'); var req = new XMLHttpRequest(); req.onreadystatechange = function () { if (req.readyState==4) { console.log(req.responseText); output.innerHTML = ""; var categories = JSON.parse(req.responseText).records; for (var i=0;i function ($operation, $tableName, $column, $value, $context) { return ($column['name'] == 'post_id' && !is_numeric($value)) ? 'must be numeric' : true; }, ``` -------------------------------- ### Database Authentication - Login Source: https://github.com/mevdschee/php-crud-api/blob/main/README.md Logs a user in by sending their username and password to the '/login' endpoint. The authenticated user details are stored in `$_SESSION['user']`. ```APIDOC ## Database Authentication - Login ### Description Logs a user in by sending their username and password to the '/login' endpoint. The authenticated user details are stored in `$_SESSION['user']`. ### Method POST ### Endpoint /login ### Parameters #### Request Body - **username** (string) - Required - The username for login. - **password** (string) - Required - The password for login. ### Request Example ```json { "username": "testuser", "password": "password123" } ``` ### Response #### Success Response (200) - The response depends on the API operation being performed, typically returning user data upon successful login. #### Response Example ```json { "data": [ { "id": 1, "username": "testuser" } ] } ``` ``` -------------------------------- ### Filter Records by ID (In List) Source: https://github.com/mevdschee/php-crud-api/blob/main/README.md Use the 'in' match type to filter records where a field's value is present in a comma-separated list. This example filters IDs that are either 0 or 1. ```http GET /records/categories?filter=id,in,0,1 ``` -------------------------------- ### Handlebars Client-Side Rendering with AJAX Source: https://github.com/mevdschee/php-crud-api/blob/main/examples/clients/handlebars.html This JavaScript code initializes a client-side application that fetches data from a '/api.php/records/posts' endpoint and renders it using a Handlebars template. It also sets up event handlers for editing, deleting, and submitting new posts. ```javascript function PostList(element, template) { var self = this; var url = '/api.php/records/posts'; self.edit = function() { var li = $(this).parent('li'); var id = li.find('span.id').text(); var content = li.find('span.content').text(); content = prompt('Value', content); if (content !== null) { $.ajax({ url: url + '/' + id, type: 'PUT', data: { content: content }, success: self.update }); } }; self.delete = function() { var li = $(this).parent('li'); var id = li.find('span.id').text(); if (confirm("Deleting #" + id + ". Continue?")) { $.ajax({ url: url + '/' + id, type: 'DELETE', success: self.update }); } }; self.submit = function(e) { e.preventDefault(); var content = $(this).find('input[name="content"]').val(); $.post(url, { user_id: 1, category_id: 1, content: content }, self.update); }; self.render = function(data) { element.html(Handlebars.compile(template.html())(data)); }; self.update = function() { $.get(url, self.render); }; self.post = function() { $.post(url, { user_id: 1, category_id: 1, content: "from handlebars" }, self.update); }; element.on('submit', 'form', self.submit); element.on('click', 'a.edit', self.edit) element.on('click', 'a.delete', self.delete) self.post(); }; $(function() { new PostList($('#PostListDiv'), $('#PostListTemplate')); }); ``` -------------------------------- ### Filter Records by ID (Lower or Equal) Source: https://github.com/mevdschee/php-crud-api/blob/main/README.md Use the 'le' match type to filter records where a numeric field is less than or equal to a specified value. This example filters IDs less than or equal to 1. ```http GET /records/categories?filter=id,le,1 ``` -------------------------------- ### Create a New Record Source: https://github.com/mevdschee/php-crud-api/blob/main/README.md Use a POST request to the /records/posts endpoint with a JSON body to create a new record. The response will be the primary key of the new record. ```http POST /records/posts { "title": "Black is the new red", "content": "This is the second post.", "created": "2018-03-06T21:34:01Z" } ``` ```text 2 ``` -------------------------------- ### Configure Page Limits for Pages and Records Source: https://github.com/mevdschee/php-crud-api/blob/main/README.md Define limits for list operations using the 'pageLimits' middleware. This configuration allows a maximum of 10 pages and 25 records per page. ```php 'pageLimits.pages' => 10, 'pageLimits.records' => 25, ``` -------------------------------- ### XML Output with XML Middleware Source: https://github.com/mevdschee/php-crud-api/blob/main/README.md Use the 'xml' middleware to translate API responses from JSON to XML. Append '?format=xml' to the request URL to receive XML output. ```http GET /records/posts/1?format=xml ``` -------------------------------- ### Database Authentication Middleware Configuration Source: https://github.com/mevdschee/php-crud-api/blob/main/README.md Minimal configuration for database authentication and authorization. It restricts access to tables other than 'users' for authorization handlers. ```php 'middlewares' => 'dbAuth,authorization', 'authorization.tableHandler' => function ($operation, $tableName) { return $tableName != 'users'; }, ``` -------------------------------- ### Angular2 Component for CRUD API Interaction Source: https://github.com/mevdschee/php-crud-api/blob/main/examples/clients/angular2.html This Angular2 component demonstrates how to interact with the PHP CRUD API. It includes setting up the component, making a POST request to create a new record, and a GET request to retrieve records. ```typescript AppComponent = ng.core.Component({ selector: 'my-app', providers: [ng.http.HTTP_PROVIDERS], template: '
  • {{ x.id + ", " + x.content }}
' }) .Class({ constructor: [ ng.http.Http, function(http) { var url = "/api.php/records/posts"; http.post(url,JSON.stringify({user_id:1,category_id:1,content:"from angular2"})).subscribe(); http.get(url).map(res => res.json()).subscribe(res => this.posts = res.records); }] }); document.addEventListener("DOMContentLoaded", function(event) { ng.core.enableProdMode(); ng.platform.browser.bootstrap(AppComponent); }); ``` -------------------------------- ### Client-Side Authentication and API Request Source: https://github.com/mevdschee/php-crud-api/blob/main/examples/clients/auth.php/vanilla.html This JavaScript code handles obtaining an access token and making an authenticated GET request to the PHP CRUD API. It redirects to an auth URL if no token is found, otherwise it fetches and displays records. ```javascript var authUrl = 'auth.php'; // url of 'auth.php' from php-api-auth var clientId = 'default'; // client id as defined in php-api-auth var audience = 'api.php'; // api audience as defined in php-api-auth window.onload = function () { var match = RegExp('[#&]access_token=([^&]*)').exec(window.location.hash); var accessToken = match && decodeURIComponent(match[1].replace(/\+/g, ' ')); if (!accessToken) { document.location = authUrl+'?audience='+audience+'&response_type=token&client_id='+clientId+'&redirect_uri='+document.location.href; } else { document.location.hash = ''; var req = new XMLHttpRequest(); req.onreadystatechange = function () { if (req.readyState==4) { console.log(req.responseText); document.getElementById('output').innerHTML = JSON.stringify(JSON.parse(req.responseText), undefined, 4); } } url = 'api.php/records/posts?join=categories&join=tags&join=comments&filter=id,eq,1'; req.open("GET", url, true); req.setRequestHeader('X-Authorization', 'Bearer '+accessToken); req.send(); } }; ``` -------------------------------- ### Batch Read Records Source: https://github.com/mevdschee/php-crud-api/blob/main/README.md Retrieve multiple records by specifying their primary keys in the URL. The result is an array of matching records. ```http GET /records/posts/1,2 ``` -------------------------------- ### Paginate categories by 'id' ascending, page 1 Source: https://github.com/mevdschee/php-crud-api/blob/main/README.md Retrieve the first page of categories, ordered by 'id' in ascending order. The default page size is 20. ```http GET /records/categories?order=id&page=1 ``` -------------------------------- ### Update Project Dependencies Source: https://github.com/mevdschee/php-crud-api/blob/main/README.md Run this command to update all project dependencies using Composer. It also patches dependencies for PHP 7.0 compatibility. ```bash php update.php ``` -------------------------------- ### Wordpress Authentication Routes Source: https://github.com/mevdschee/php-crud-api/blob/main/README.md Provides routes for user authentication and session management using Wordpress. ```APIDOC ## GET /me ### Description Returns the user that is currently logged in. ### Method GET ### Endpoint /me ## POST /login ### Description Logs a user in by username and password. ### Method POST ### Endpoint /login ### Parameters #### Request Body - **username** (string) - Required - The username for login. - **password** (string) - Required - The password for login. ## POST /logout ### Description Logs out the currently logged in user. ### Method POST ### Endpoint /logout ``` -------------------------------- ### Create Record Source: https://github.com/mevdschee/php-crud-api/blob/main/README.md Creates a new record in the specified table. Requires a JSON body with the fields to be inserted. ```APIDOC ## POST /records/posts ### Description Creates a new record in the posts table. ### Method POST ### Endpoint /records/posts ### Request Body - **title** (string) - Required - The title of the post. - **content** (string) - Required - The content of the post. - **created** (string) - Required - The creation timestamp in ISO 8601 format. ### Request Example { "title": "Black is the new red", "content": "This is the second post.", "created": "2018-03-06T21:34:01Z" } ### Response #### Success Response (200) - **integer** - The primary key of the newly created record. ```