Installing BowPHP
Introductionβ
BowPHP is a modern and elegant PHP micro-framework. Before creating your first application, make sure your environment meets the following requirements.
System requirementsβ
- PHP >= 8.2
- OpenSSL PHP Extension
- PDO PHP Extension
- Mbstring PHP Extension
- XML PHP Extension
- JSON PHP Extension
Creating a projectβ
BowPHP uses Composer to manage its dependencies. Make sure Composer is installed on your machine before continuing.
Installation via Composerβ
composer create-project --prefer-dist bowphp/app nom-du-projet
We recommend installing Composer globally on your machine. Check the official documentation for installation instructions.
If you're new to Composer, take the time to go through its documentation to understand how it works.
Starting your projectβ
Go to the root of your project and start the development server:
cd nom-du-projet
php bow run:server --port=8080 --host=0.0.0.0
Open your browser and go to http://localhost:8080.
If you don't specify a port, the server starts on port 5000 by default:
php bow run:server
# Accessible at http://localhost:5000
Configurationβ
Public folderβ
After installation, configure your web server's document root to point to the public folder.
The index.php file located in this folder serves as the single entry point for all HTTP requests (the Front Controller pattern).
Configuration filesβ
All of BowPHP's configuration files are located in the config folder. Each option is documented to make it easy to customize your application.
Structure of the config folder:
app.php: Application configurationdatabase.php: Database configurationmail.php: Email sending configuration- And many more...
Folder permissionsβ
The folders contained in var must have write permissions for the web server:
# On Linux/macOS
chmod -R 775 var/
chown -R www-data:www-data var/
Make sure the web server has write permissions on the var folder so that logs, cache, and sessions work correctly.
Web server configurationβ
Apacheβ
Bow includes a public/.htaccess file that handles URL rewriting to the front controller.
Requirement: The mod_rewrite module must be enabled.
# Enable mod_rewrite on Ubuntu/Debian
sudo a2enmod rewrite
sudo systemctl restart apache2
If the default .htaccess file doesn't work, try this alternative configuration:
Options +FollowSymLinks
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
Nginxβ
For Nginx, add this configuration to your site file:
server {
listen 80;
server_name example.com www.example.com;
root /var/www/bow-app/public;
index index.php;
# Logs
access_log /var/log/nginx/bow-app.access.log;
error_log /var/log/nginx/bow-app.error.log;
# Security - Headers
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
# Gzip compression
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_types text/plain text/css text/xml text/javascript
application/javascript application/json application/xml;
# Front Controller
location / {
try_files $uri $uri/ /index.php?$query_string;
}
# PHP-FPM
location ~ \.php$ {
fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
include fastcgi_params;
fastcgi_hide_header X-Powered-By;
}
# Static assets cache
location ~* \.(css|js|jpg|jpeg|png|gif|ico|svg|woff|woff2|ttf|eot)$ {
expires 1y;
add_header Cache-Control "public, immutable";
access_log off;
}
# Block access to sensitive files
location ~ /\.(env|git|htaccess) {
deny all;
}
location ~ ^/(var|vendor|config|migrations|seeders)/ {
deny all;
}
}
Nginx with SSL (HTTPS)β
server {
listen 80;
server_name example.com www.example.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name example.com www.example.com;
root /var/www/bow-app/public;
index index.php;
# SSL certificates (Let's Encrypt)
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
# Modern SSL configuration
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
ssl_prefer_server_ciphers off;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_stapling on;
ssl_stapling_verify on;
# Security headers
add_header Strict-Transport-Security "max-age=63072000" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
include fastcgi_params;
}
location ~ /\.(env|git|htaccess) {
deny all;
}
}
Enabling the Nginx siteβ
# Create the symbolic link
sudo ln -s /etc/nginx/sites-available/bow-app /etc/nginx/sites-enabled/
# Test the configuration
sudo nginx -t
# Reload Nginx
sudo systemctl reload nginx
Dockerβ
To develop with Docker, create the following files at the root of the project:
FROM php:8.2-fpm-alpine
# PHP extensions
RUN apk add --no-cache \
libpng-dev libjpeg-turbo-dev freetype-dev \
oniguruma-dev libxml2-dev zip unzip git curl \
&& docker-php-ext-configure gd --with-freetype --with-jpeg \
&& docker-php-ext-install pdo pdo_mysql mbstring xml gd opcache
# Composer
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
WORKDIR /var/www/html
COPY . .
RUN composer install --no-dev --optimize-autoloader \
&& chown -R www-data:www-data var/
EXPOSE 9000
CMD ["php-fpm"]
services:
app:
build: .
volumes:
- .:/var/www/html
- ./var:/var/www/html/var
depends_on:
- mysql
- redis
networks:
- bow-network
nginx:
image: nginx:alpine
ports:
- "8080:80"
volumes:
- .:/var/www/html
- ./docker/nginx.conf:/etc/nginx/conf.d/default.conf
depends_on:
- app
networks:
- bow-network
mysql:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: secret
MYSQL_DATABASE: bow_app
MYSQL_USER: bow
MYSQL_PASSWORD: secret
volumes:
- mysql-data:/var/lib/mysql
ports:
- "3306:3306"
networks:
- bow-network
redis:
image: redis:alpine
ports:
- "6379:6379"
networks:
- bow-network
networks:
bow-network:
driver: bridge
volumes:
mysql-data:
server {
listen 80;
root /var/www/html/public;
index index.php;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
fastcgi_pass app:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
include fastcgi_params;
}
}
# Start the containers
docker-compose up -d
# Access the application
# http://localhost:8080
Deploying on shared hostingβ
To deploy BowPHP on shared hosting:
- Move the
index.phpand.htaccessfiles from thepublicfolder to the root of the project - Update the paths in
index.phpso that they correctly point to the framework folders - Use the following
.htaccessconfiguration:
Options -indexes
<IfModule mod_rewrite.c>
<IfModule mod_negotiation.c>
Options -MultiViews
</IfModule>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ /$1 [L,R=301]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
</IfModule>
<Files ".env.*|server.php|bow|app/**|vendor/**|postman/*|var/**|seeders/*|templates/**|tests/**|migrations/**">
Order Allow,Deny
Deny from all
</Files>
For shared hosting, use the app_assets() helper for your static files and change the value of APP_ASSET_PREFIX to /public in your .env.json file. Bow will automatically handle the correct paths!
Next stepsβ
Now that your installation is complete, learn how to build your application:
- Create your first routes
- Use controllers
- Work with databases
- Manage user sessions
- Use the storage system
- Create views with Tintin
Is something missing?
If you run into problems with the documentation or have suggestions to improve the documentation or the project in general, please open an issue for us, or send a tweet mentioning the Twitter account @bowframework or directly on github.