How to create API with Pure PHP?
In this project we will create a Simple API using only PHP in any framework. All we will need will be:
- PHP - Essential
- Composer - Essential
- Editor/IDE like VScode or PHPStorm
- Docker - Preferred but not essential
- Postman - Preferred, but not essential
Let's start by defining our docker-compose.yml file for our database configuration. If you don't want to use Docker to create a database in containers, a solution is to install the database on your machine. For this tutorial we will use MySQL.
Settings
After creating the folder where our application will be located, we start by configuring docker-compose.yaml:
services: mysql: image: mysql:9.1.0 ports: - '3306:3306' environment: MYSQL_ROOT_PASSWORD: useroot MYSQL_USER: api_user MYSQL_PASSWORD: api_password MYSQL_DATABASE: api_example
Let's break this file into parts for explanation:
services: mysql:
In this file we are defining the services that will be used.
I'm naming this service mysql. Attention, the name of this service will be used to connect to the database as host
image: mysql:9.1.0
Next I am defining which image will be used to create our database, for this project I am using version 9.1.0 of mysql.
You can find this and other versions on Docker Hub.
ports: - '3306:3306'
The port is being set to 3306. This is the default mysql port!
You can notice that the port is like 3306:3306, this : means that we want to listen to this port on our local machine and not just on the docker container, so we can access it it directly on our machine.
environment: MYSQL_ROOT_PASSWORD: useroot MYSQL_USER: api_user MYSQL_PASSWORD: api_password MYSQL_DATABASE: api_example
As an environment we must define the credentials for our mysql service.
Therefore, we are defining user, password and database name using environment variables:
MYSQL_USER: api_user // <--- Este é nosso usuário
MYSQL_PASSWORD: api_password // <--- Este é nosso password
MYSQL_DATABASE: api_example // <--- Este é nosso banco de dados
MYSQL_ROOT_PASSWORD: useroot // <--- Está é a senha para o usuário root
To start our container, just be inside the folder where the docker-compose.yaml file is located and type the following command in our terminal:
docker compose up -d
This will initialize the mysql service in our container.
If you want to access mysql within the terminal, you can use this command:
docker exec -it <nome do container> bash
After typing this command and pressing enter you will enter the container where the mysql image is running.
The container name is formed by foldername-hostname-number
In this case, the name of our container would be: create-api-php-mysql-1 if our application was created within the "create-api-php" directory.
We will also create a composer.json file, this file will serve as the basis for installing external libraries that will be used in the project. In this project we will only use Dotenv.
services: mysql: image: mysql:9.1.0 ports: - '3306:3306' environment: MYSQL_ROOT_PASSWORD: useroot MYSQL_USER: api_user MYSQL_PASSWORD: api_password MYSQL_DATABASE: api_example
In this line we are adding the most used library for dotenv in php.
You can find the repository for this lib at: Github Vlucas Repository
services: mysql:
In the line below we are basically saying that we will use autoload with the default configuration of the PSR-4. The most used PSRs currently are PSR-12 and PSR-4, with 12 being the most used to date. But for now we will continue using the PSR-4.
image: mysql:9.1.0
With these two files created we can give the command
ports: - '3306:3306'
It will install the Dotenv library and configure the settings for the desired PSR.
After this command, the composer.lock.
For those coming from the JavaScript world, these files can be compared with package.json and package-lock.json.
You will also see that a folder has been added to your directory with the name vendor. It contains our Dotenv lib and also a very important file: autoload.php.
We do not need to touch or change anything in this file, as it will be responsible for transacting Dotenv information between our other files.
We will also create a file called bootstrap.php, this file is responsible for initializing our application and connecting some important parameters so that everything works as expected:
environment: MYSQL_ROOT_PASSWORD: useroot MYSQL_USER: api_user MYSQL_PASSWORD: api_password MYSQL_DATABASE: api_example
We can then create the .env file to add the environment variables that will be responsible for connecting to our mysql database.
We then add:
MYSQL_USER: api_user // <--- Este é nosso usuário
We will also create a .env.example file where a copy of this information will be saved in case someone wants to clone our repository or even for us in the future if we want to continue our project, this way we will have the necessary information to know what we need define and what we don't need.
MYSQL_PASSWORD: api_password // <--- Este é nosso password
The reason we will create these two files, one containing all the information and the other containing only part of the information, is because the .env file should not be uploaded to the repository, as it contains confidential information. Let's say that in the future we want to use a third-party API where we need to add a token for access, then we will store this information within the .env file.
To prevent the .env file from being uploaded to our repository we will create a file called .gitignore and add the following information:
MYSQL_DATABASE: api_example // <--- Este é nosso banco de dados
This way we define that the .env file and the entire contents of the vendor folder will not be committed.
With this we have finished configuring our project and are free to continue coding.
Codification
We will create the following directories src/System and within System the file DatabaseConnector.php
services: mysql: image: mysql:9.1.0 ports: - '3306:3306' environment: MYSQL_ROOT_PASSWORD: useroot MYSQL_USER: api_user MYSQL_PASSWORD: api_password MYSQL_DATABASE: api_example
Here we are defining a namespace for this file, so that we can use it in the future within other files.
services: mysql:
We will create our class with the same name as the file and create a private variable named $dbConnection passing the value null.
This variable will be responsible for a new instance of this class and connecting us with the database.
We'll see more later when we implement try-catch.
image: mysql:9.1.0
Within the constructor we will create the following variables and check the values captured from the .env file with Dotenv.
ports: - '3306:3306'
Still inside the constructor we will do a try-catch to validate the action we want to perform:
environment: MYSQL_ROOT_PASSWORD: useroot MYSQL_USER: api_user MYSQL_PASSWORD: api_password MYSQL_DATABASE: api_example
Within this try we are trying to create a new instance of our class and passing it into the $dbConnection variable. We are using a PDO module for this where it receives the parameters
- DSN - Data Source Name or URI
- - mysql: Being the service/bank we are using.
- - host=$host; Our Host
- - port=$port; Our door
- - charset=utf8mb4; Definition of the utf8 charset for the database
- - dbname=$db The Name of our database
- USER - User to login to the database
- PASS - Password for logging into the database
Error case:
MYSQL_USER: api_user // <--- Este é nosso usuário
We will trigger an exception from PDO and return the error message.
Clearly this is just an example of how we should present errors in a development environment. For production environments, it is good practice to present more concise errors that help us understand the problem more clearly.
Outside the constructor but inside our class, we will create the following function:
MYSQL_PASSWORD: api_password // <--- Este é nosso password
Being responsible for calling our variable containing the instance of our connection.
Remember our bootstrap.php file? Let's add the following lines of code to it:
MYSQL_DATABASE: api_example // <--- Este é nosso banco de dados
Looking like this:
MYSQL_ROOT_PASSWORD: useroot // <--- Está é a senha para o usuário root
Inside the folder src we will create another directory with the name Database and inside it the file database_seed.php.
This file will be responsible for populating our database for the first time, so if we want to share this project with someone it will not end up with an empty database.
Inside this file we will add the following codes:
services: mysql: image: mysql:9.1.0 ports: - '3306:3306' environment: MYSQL_ROOT_PASSWORD: useroot MYSQL_USER: api_user MYSQL_PASSWORD: api_password MYSQL_DATABASE: api_example
We import require 'bootstrap.php'; because within our bootstrap file we have already imported the variable that is responsible for instantiating our database.
services: mysql:
We create a variable with the name $statement that has a value of Heredoc
image: mysql:9.1.0
Within this Heredoc we will add some querys:
ports: - '3306:3306'
Here I am opting for drop table to drop the entire base and then start a new one, however if you want you can remove this line of code.
The following line of code specifies that this table will be used to carry out transactions and will have a connection between the tables. If you want to learn more about this mysql declaration: innoDb documentation
environment: MYSQL_ROOT_PASSWORD: useroot MYSQL_USER: api_user MYSQL_PASSWORD: api_password MYSQL_DATABASE: api_example
Within the same Heredoc we will add another query:
MYSQL_USER: api_user // <--- Este é nosso usuário
Here we are inserting some data into the person table.
We create a try-catch at the end of the file where we try to initialize the querys and in case of error we return an error message just as we did in the data processing in the codes above.
MYSQL_PASSWORD: api_password // <--- Este é nosso password
Inside src we will create another directory with the name TableGateways and inside it we will create the file: PersonGateway.php.
MYSQL_DATABASE: api_example // <--- Este é nosso banco de dados
The files inside this folder will be responsible for interacting with our database, almost like a Repository.
In our PersonGateway class we will add the following constructor:
MYSQL_ROOT_PASSWORD: useroot // <--- Está é a senha para o usuário root
We will add this constructor because our class will be called in other files so that we can trigger some methods of our class.
See the following methods:
Method responsible for listing all users in our table
docker compose up -d
Method responsible for listing a single user from our table
docker exec -it <nome do container> bash
Responsible method to insert a user into our table
{ "require": { "vlucas/phpdotenv": "^2.4" }, "autoload": { "psr-4": { "Src\": "src/" } } }
Method responsible for updating a user's information in our table
"require": { "vlucas/phpdotenv": "^2.4" },
Method responsible for deleting a user from our table
"autoload": { "psr-4": { "Src\": "src/" } }
We will create within src a directory with the name Controller and inside it the file: PersonController.php.
The files within this directory are responsible for interacting with our application route. Here we interact directly with the bank, but we could use a services layer and limit all logic and business rules to this layer.
If you want to create the services layer, it would be like this:
services: mysql: image: mysql:9.1.0 ports: - '3306:3306' environment: MYSQL_ROOT_PASSWORD: useroot MYSQL_USER: api_user MYSQL_PASSWORD: api_password MYSQL_DATABASE: api_example
However, our intention is not to delve deeper into this type of architecture, for now we will continue with the controller file:
services: mysql:
Inside our PersonController class we will add:
image: mysql:9.1.0
This way we guarantee that we are interacting with a new instance of our database.
We also created a method to process our requests:
ports: - '3306:3306'
This header is responsible for transmitting the status code and if a body is created it returns this same body to be viewed.
environment: MYSQL_ROOT_PASSWORD: useroot MYSQL_USER: api_user MYSQL_PASSWORD: api_password MYSQL_DATABASE: api_example
We also created the methods that will interact with the routes:
Method responsible for interacting with the user's listing route
MYSQL_USER: api_user // <--- Este é nosso usuário
Method responsible for interacting with the user's creation route
MYSQL_PASSWORD: api_password // <--- Este é nosso password
Method responsible for interacting with the user's update route
MYSQL_DATABASE: api_example // <--- Este é nosso banco de dados
Method responsible for interacting with the user's deletion route
MYSQL_ROOT_PASSWORD: useroot // <--- Está é a senha para o usuário root
Methods responsible for validation
docker compose up -d
docker exec -it <nome do container> bash
{ "require": { "vlucas/phpdotenv": "^2.4" }, "autoload": { "psr-4": { "Src\": "src/" } } }
Finally, we will create a directory outside our folder src with the name Public.
This folder is responsible for containing the php display file.
We will create the file inside it: index.php
We will add the following code:
"require": { "vlucas/phpdotenv": "^2.4" },
This file is responsible for setting the headers and checking access to the url. If the access is successful it returns the contents, if not it returns an error.
To access your application, simply upload a server using the internal PHP server:
"autoload": { "psr-4": { "Src\": "src/" } }
if you have not initialized the container, type the following command in the terminal:
composer install
Now just use postman or any other application that helps you interact with url.
My social networks:
Github Linkedin
The above is the detailed content of How to create API with Pure PHP?. For more information, please follow other related articles on the PHP Chinese website!

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics











JWT is an open standard based on JSON, used to securely transmit information between parties, mainly for identity authentication and information exchange. 1. JWT consists of three parts: Header, Payload and Signature. 2. The working principle of JWT includes three steps: generating JWT, verifying JWT and parsing Payload. 3. When using JWT for authentication in PHP, JWT can be generated and verified, and user role and permission information can be included in advanced usage. 4. Common errors include signature verification failure, token expiration, and payload oversized. Debugging skills include using debugging tools and logging. 5. Performance optimization and best practices include using appropriate signature algorithms, setting validity periods reasonably,

Session hijacking can be achieved through the following steps: 1. Obtain the session ID, 2. Use the session ID, 3. Keep the session active. The methods to prevent session hijacking in PHP include: 1. Use the session_regenerate_id() function to regenerate the session ID, 2. Store session data through the database, 3. Ensure that all session data is transmitted through HTTPS.

RESTAPI design principles include resource definition, URI design, HTTP method usage, status code usage, version control, and HATEOAS. 1. Resources should be represented by nouns and maintained at a hierarchy. 2. HTTP methods should conform to their semantics, such as GET is used to obtain resources. 3. The status code should be used correctly, such as 404 means that the resource does not exist. 4. Version control can be implemented through URI or header. 5. HATEOAS boots client operations through links in response.

In PHP, exception handling is achieved through the try, catch, finally, and throw keywords. 1) The try block surrounds the code that may throw exceptions; 2) The catch block handles exceptions; 3) Finally block ensures that the code is always executed; 4) throw is used to manually throw exceptions. These mechanisms help improve the robustness and maintainability of your code.

The main function of anonymous classes in PHP is to create one-time objects. 1. Anonymous classes allow classes without names to be directly defined in the code, which is suitable for temporary requirements. 2. They can inherit classes or implement interfaces to increase flexibility. 3. Pay attention to performance and code readability when using it, and avoid repeatedly defining the same anonymous classes.

In PHP, the difference between include, require, include_once, require_once is: 1) include generates a warning and continues to execute, 2) require generates a fatal error and stops execution, 3) include_once and require_once prevent repeated inclusions. The choice of these functions depends on the importance of the file and whether it is necessary to prevent duplicate inclusion. Rational use can improve the readability and maintainability of the code.

There are four main error types in PHP: 1.Notice: the slightest, will not interrupt the program, such as accessing undefined variables; 2. Warning: serious than Notice, will not terminate the program, such as containing no files; 3. FatalError: the most serious, will terminate the program, such as calling no function; 4. ParseError: syntax error, will prevent the program from being executed, such as forgetting to add the end tag.

PHP and Python each have their own advantages, and choose according to project requirements. 1.PHP is suitable for web development, especially for rapid development and maintenance of websites. 2. Python is suitable for data science, machine learning and artificial intelligence, with concise syntax and suitable for beginners.
