Home Backend Development PHP Tutorial How to create API with Pure PHP?

How to create API with Pure PHP?

Nov 04, 2024 am 06:11 AM

Como criar API com PHP Puro?

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
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

Let's break this file into parts for explanation:

services:
  mysql:
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

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
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

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'
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

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
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

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
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
MYSQL_PASSWORD: api_password // <--- Este é nosso password
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
MYSQL_DATABASE: api_example // <--- Este é nosso banco de dados
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login
MYSQL_ROOT_PASSWORD: useroot // <--- Está é a senha para o usuário root
Copy after login
Copy after login
Copy after login
Copy after login

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
Copy after login
Copy after login
Copy after login

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
Copy after login
Copy after login
Copy after login

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
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

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:
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

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
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

With these two files created we can give the command

ports:
      - '3306:3306'
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

It will install the Dotenv library and configure the settings for the desired PSR.
After this command, the composer.lock.

file will be created in our environment

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
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

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
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

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
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

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
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

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
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

Here we are defining a namespace for this file, so that we can use it in the future within other files.

services:
  mysql:
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

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
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

Within the constructor we will create the following variables and check the values ​​captured from the .env file with Dotenv.

ports:
      - '3306:3306'
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

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
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

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
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

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
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

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
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

Looking like this:

MYSQL_ROOT_PASSWORD: useroot // <--- Está é a senha para o usuário root
Copy after login
Copy after login
Copy after login
Copy after login

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
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

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:
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

We create a variable with the name $statement that has a value of Heredoc

image: mysql:9.1.0
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

Within this Heredoc we will add some querys:

ports:
      - '3306:3306'
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

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
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

Within the same Heredoc we will add another query:

MYSQL_USER: api_user // <--- Este é nosso usuário
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

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
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

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
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

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
Copy after login
Copy after login
Copy after login
Copy after login

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
Copy after login
Copy after login
Copy after login

Method responsible for listing a single user from our table

docker exec -it <nome do container> bash
Copy after login
Copy after login
Copy after login

Responsible method to insert a user into our table

{
  "require": {
      "vlucas/phpdotenv": "^2.4"
  },
  "autoload": {
      "psr-4": {
          "Src\": "src/"
      }
  }
}
Copy after login
Copy after login

Method responsible for updating a user's information in our table

"require": {
      "vlucas/phpdotenv": "^2.4"
},
Copy after login
Copy after login

Method responsible for deleting a user from our table

"autoload": {
      "psr-4": {
          "Src\": "src/"
      }
  }
Copy after login
Copy after login

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
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

However, our intention is not to delve deeper into this type of architecture, for now we will continue with the controller file:

services:
  mysql:
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

Inside our PersonController class we will add:

image: mysql:9.1.0
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

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'
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

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
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

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
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

Method responsible for interacting with the user's creation route

MYSQL_PASSWORD: api_password // <--- Este é nosso password
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

Method responsible for interacting with the user's update route

MYSQL_DATABASE: api_example // <--- Este é nosso banco de dados
Copy after login
Copy after login
Copy after login
Copy after login
Copy after login

Method responsible for interacting with the user's deletion route

MYSQL_ROOT_PASSWORD: useroot // <--- Está é a senha para o usuário root
Copy after login
Copy after login
Copy after login
Copy after login

Methods responsible for validation

docker compose up -d
Copy after login
Copy after login
Copy after login
docker exec -it <nome do container> bash
Copy after login
Copy after login
Copy after login
{
  "require": {
      "vlucas/phpdotenv": "^2.4"
  },
  "autoload": {
      "psr-4": {
          "Src\": "src/"
      }
  }
}
Copy after login
Copy after login

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"
},
Copy after login
Copy after login

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/"
      }
  }
Copy after login
Copy after login

if you have not initialized the container, type the following command in the terminal:

composer install
Copy after login

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!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

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

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

Hot Topics

Java Tutorial
1655
14
PHP Tutorial
1252
29
C# Tutorial
1226
24
Explain JSON Web Tokens (JWT) and their use case in PHP APIs. Explain JSON Web Tokens (JWT) and their use case in PHP APIs. Apr 05, 2025 am 12:04 AM

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,

How does session hijacking work and how can you mitigate it in PHP? How does session hijacking work and how can you mitigate it in PHP? Apr 06, 2025 am 12:02 AM

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.

What is REST API design principles? What is REST API design principles? Apr 04, 2025 am 12:01 AM

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.

How do you handle exceptions effectively in PHP (try, catch, finally, throw)? How do you handle exceptions effectively in PHP (try, catch, finally, throw)? Apr 05, 2025 am 12:03 AM

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.

What are anonymous classes in PHP and when might you use them? What are anonymous classes in PHP and when might you use them? Apr 04, 2025 am 12:02 AM

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.

What is the difference between include, require, include_once, require_once? What is the difference between include, require, include_once, require_once? Apr 05, 2025 am 12:07 AM

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.

Explain different error types in PHP (Notice, Warning, Fatal Error, Parse Error). Explain different error types in PHP (Notice, Warning, Fatal Error, Parse Error). Apr 08, 2025 am 12:03 AM

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: Comparing Two Popular Programming Languages PHP and Python: Comparing Two Popular Programming Languages Apr 14, 2025 am 12:13 AM

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.

See all articles