Skip to main content

Overview

The PHP backend handles legacy functionality and provides database connectivity for certain components of the Mis Compras platform. It works alongside the Node.js backend to provide a complete marketplace solution.

Prerequisites

Ensure you have completed the database setup before proceeding.
  • PHP 8.3.28 or higher
  • MySQL 8.4.3+
  • Web server (Apache, Nginx, or PHP built-in server)
  • mysqli extension enabled
  • PDO MySQL extension enabled

Checking PHP Version

Verify your PHP installation:
php -v
Expected output:
PHP 8.3.28 (cli) (built: Dec 2024)

Checking Required Extensions

Verify mysqli and PDO extensions are installed:
php -m | grep -E "mysqli|pdo_mysql"
If extensions are missing, install them:
sudo apt-get install php8.3-mysql php8.3-mysqli
sudo systemctl restart apache2

Installation

1

Clone or Navigate to PHP Directory

Ensure your PHP files are in the web server’s document root:
cd /var/www/html  # Apache default
# or
cd /path/to/your/project
2

Create Database Connection File

Create the conexion.php file in your project root:
conexion.php
<?php
$servername = "127.0.0.1";
$username = "root";
$password = "";
$database = "tienda_online";
$port = 3306;  // Change from 522 to 3306 for standard MySQL

// Crear conexión
$conn = new mysqli($servername, $username, $password, $database, $port);

// Configurar charset UTF-8
$conn->set_charset("utf8mb4");

// Verificar conexión
if ($conn->connect_error) {
    die("Error de conexión: " . $conn->connect_error);
}
?>
The original configuration uses port 522, which is non-standard. Update to 3306 (default MySQL port) unless you’ve specifically configured MySQL to use port 522.
3

Set Proper Permissions

Ensure the web server can read your PHP files:
# Set ownership to web server user
sudo chown -R www-data:www-data /var/www/html

# Set appropriate permissions
sudo chmod -R 755 /var/www/html
sudo chmod 644 conexion.php
4

Test Database Connection

Create a test file to verify connectivity:
test_db.php
<?php
include 'conexion.php';

echo "<h2>Testing Database Connection</h2>";

if ($conn->ping()) {
    echo "<p style='color: green;'>✓ Database connection successful!</p>";
    
    // Test query
    $result = $conn->query("SELECT COUNT(*) as total FROM productos");
    if ($result) {
        $row = $result->fetch_assoc();
        echo "<p>Total products in database: " . $row['total'] . "</p>";
    }
} else {
    echo "<p style='color: red;'>✗ Database connection failed!</p>";
    echo "<p>Error: " . $conn->error . "</p>";
}

$conn->close();
?>
Access via browser: http://localhost/test_db.php

Configuration

Database Connection Parameters

The conexion.php file uses MySQLi extension with these parameters:
ParameterDescriptionDefaultRecommended
$servernameMySQL host address127.0.0.1127.0.0.1 or localhost
$usernameDatabase usernamerootCreate dedicated user
$passwordDatabase passwordEmptyUse strong password
$databaseDatabase nametienda_onlineKeep as is
$portMySQL port522Change to 3306

Connection Object

The $conn variable provides a MySQLi connection object used throughout the application:
// Example usage in other PHP files
include 'conexion.php';

$query = "SELECT * FROM productos WHERE id_categoria = ?";
$stmt = $conn->prepare($query);
$stmt->bind_param("i", $categoria_id);
$stmt->execute();
$result = $stmt->get_result();

while ($row = $result->fetch_assoc()) {
    // Process results
}

$stmt->close();

Character Encoding

Always set UTF-8 encoding for proper international character support:
$conn->set_charset("utf8mb4");
This ensures:
  • Spanish characters (ñ, á, é, í, ó, ú) display correctly
  • Emoji support in product descriptions
  • Consistent encoding across all data

PHP Configuration

For development:
php.ini
; Error Reporting
display_errors = On
error_reporting = E_ALL
log_errors = On
error_log = /var/log/php/error.log

; Memory and Execution
memory_limit = 256M
max_execution_time = 300
upload_max_filesize = 10M
post_max_size = 10M

; MySQL Extensions
extension=mysqli
extension=pdo_mysql

; Session Configuration
session.save_handler = files
session.save_path = "/tmp"
session.gc_maxlifetime = 1440
For production:
php.ini (Production)
; Error Reporting (Don't display errors to users)
display_errors = Off
error_reporting = E_ALL
log_errors = On
error_log = /var/log/php/error.log

; Memory and Execution
memory_limit = 128M
max_execution_time = 60
upload_max_filesize = 5M
post_max_size = 5M

; Security
expose_php = Off
allow_url_fopen = Off

File Upload Configuration

For product image uploads, ensure these settings are configured:
// Check max upload size
ini_set('upload_max_filesize', '10M');
ini_set('post_max_size', '10M');
ini_set('max_file_uploads', '20');

Running the PHP Backend

Using Apache

1

Configure Virtual Host

Create a virtual host configuration:
/etc/apache2/sites-available/tienda-online.conf
<VirtualHost *:80>
    ServerName tienda-online.local
    DocumentRoot /var/www/html/tienda-online
    
    <Directory /var/www/html/tienda-online>
        Options Indexes FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>
    
    ErrorLog ${APACHE_LOG_DIR}/tienda-error.log
    CustomLog ${APACHE_LOG_DIR}/tienda-access.log combined
</VirtualHost>
2

Enable Site and Restart Apache

sudo a2ensite tienda-online.conf
sudo systemctl restart apache2
3

Update Hosts File

Add to /etc/hosts:
127.0.0.1   tienda-online.local

Using PHP Built-in Server

For development only:
# Navigate to your PHP project directory
cd /path/to/tienda-online

# Start PHP built-in server
php -S localhost:8000
Access via: http://localhost:8000
The PHP built-in server is for development only. Never use it in production.

Using Nginx

Configure Nginx for PHP:
/etc/nginx/sites-available/tienda-online
server {
    listen 80;
    server_name tienda-online.local;
    root /var/www/html/tienda-online;
    
    index index.php index.html;
    
    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }
    
    location ~ \.php$ {
        fastcgi_pass unix:/var/run/php/php8.3-fpm.sock;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    }
    
    location ~ /\.ht {
        deny all;
    }
}
Enable and restart:
sudo ln -s /etc/nginx/sites-available/tienda-online /etc/nginx/sites-enabled/
sudo systemctl restart nginx
sudo systemctl restart php8.3-fpm

Security Considerations

Database Connection Security

Never commit conexion.php with real credentials to version control.
Create a template file instead:
conexion.example.php
<?php
$servername = "127.0.0.1";
$username = "your_db_username";
$password = "your_db_password";
$database = "tienda_online";
$port = 3306;

$conn = new mysqli($servername, $username, $password, $database, $port);
$conn->set_charset("utf8mb4");

if ($conn->connect_error) {
    error_log("Database connection failed: " . $conn->connect_error);
    die("Database connection error");
}
?>

SQL Injection Prevention

Always use prepared statements:
// WRONG - Vulnerable to SQL injection
$id = $_GET['id'];
$query = "SELECT * FROM productos WHERE id_producto = $id";
$result = $conn->query($query);

// CORRECT - Safe from SQL injection
$id = $_GET['id'];
$query = "SELECT * FROM productos WHERE id_producto = ?";
$stmt = $conn->prepare($query);
$stmt->bind_param("i", $id);
$stmt->execute();
$result = $stmt->get_result();

Password Hashing

The platform uses bcrypt for password hashing:
// Registration
$password = $_POST['password'];
$hashed = password_hash($password, PASSWORD_BCRYPT);

// Verification
if (password_verify($password, $hashed_from_db)) {
    // Login successful
}

Troubleshooting

Connection Errors

Error: “Connection refused”
# Check if MySQL is running
sudo systemctl status mysql

# Start MySQL if needed
sudo systemctl start mysql
Error: “Access denied for user”
  • Verify username and password in conexion.php
  • Check MySQL user privileges:
SHOW GRANTS FOR 'root'@'localhost';
Error: “Unknown database ‘tienda_online‘“
CREATE DATABASE tienda_online;

Port Issues

If MySQL runs on a different port:
# Find MySQL port
mysqladmin variables | grep port

# Update conexion.php with correct port

Extension Errors

Error: “Call to undefined function mysqli_connect()“
# Install mysqli extension
sudo apt-get install php-mysqli
sudo systemctl restart apache2

Testing the Backend

Create a comprehensive test suite:
test_suite.php
<?php
include 'conexion.php';

echo "<h1>Backend Test Suite</h1>";

// Test 1: Connection
echo "<h2>Test 1: Database Connection</h2>";
if ($conn->ping()) {
    echo "✓ PASS<br>";
} else {
    echo "✗ FAIL: " . $conn->error . "<br>";
}

// Test 2: Table access
echo "<h2>Test 2: Table Access</h2>";
$tables = ['usuarios', 'productos', 'categorias', 'carrito', 'pedidos'];
foreach ($tables as $table) {
    $result = $conn->query("SELECT COUNT(*) FROM $table");
    echo $result ? "✓ $table accessible<br>" : "✗ $table error<br>";
}

// Test 3: Character encoding
echo "<h2>Test 3: UTF-8 Support</h2>";
$result = $conn->query("SELECT @@character_set_database");
$row = $result->fetch_row();
echo "Charset: " . $row[0] . "<br>";

$conn->close();
?>

Next Steps

After configuring the PHP backend:
  1. Set up the Node.js backend
  2. Configure environment variables
  3. Test the complete stack with both backends running

Build docs developers (and LLMs) love