Module 15: Deployment
Lesson 1: Understanding Hosting Options
- Duration: 90 minutes
- Learning objectives:
- Compare shared hosting, VPS, and free hosting options
- Identify the pros and cons of each hosting type
- Choose the right hosting for a beginner project
- Set realistic expectations for performance and cost
Instructor notes
Most beginners confuse hosting types. Emphasize that shared hosting is the easiest starting point, but free hosts like InfinityFree have limitations (ads, downtime, no root access). Use analogies: shared hosting is like renting a room in a shared house; VPS is like owning an apartment building.
Presentation outline
- What is web hosting?
- Types of hosting: shared, VPS, dedicated, cloud, free
- Comparing cost, control, and difficulty
- Free hosting options: InfinityFree, 000webhost, Netlify
- Choosing the right host for your project
Demonstration
- Visit InfinityFree.net and create a free account
- Compare control panel features with a paid shared host
- Review file manager and database creation tools
- Test a live site URL
AI prompts
- "Compare shared hosting vs VPS for a beginner PHP MySQL project. Include cost, setup difficulty, and maintenance requirements."
- "List 5 free hosting providers that support PHP and MySQL. Rank them by reliability and ease of use for beginners."
- "What are the limitations of free hosting providers? How do they affect a production e-commerce website?"
Starter code
<!-- hosting-comparison.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Hosting Comparison</title>
<style>
table { border-collapse: collapse; width: 100%; }
th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
th { background-color: #f2f2f2; }
</style>
</head>
<body>
<h1>Hosting Comparison</h1>
<table>
<tr>
<th>Host Type</th>
<th>Cost</th>
<th>Control</th>
<th>Difficulty</th>
</tr>
<tr>
<td>Shared</td>
<td>$3-10/month</td>
<td>Low</td>
<td>Easy</td>
</tr>
<tr>
<td>VPS</td>
<td>$5-20/month</td>
<td>High</td>
<td>Medium</td>
</tr>
<tr>
<td>Free</td>
<td>$0</td>
<td>Very Low</td>
<td>Easy</td>
</tr>
</table>
</body>
</html>
Final code
<!-- hosting-comparison.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Hosting Comparison</title>
<style>
body { font-family: Arial, sans-serif; max-width: 1000px; margin: 0 auto; padding: 20px; }
table { border-collapse: collapse; width: 100%; margin-top: 20px; }
th, td { border: 1px solid #ddd; padding: 12px; text-align: left; }
th { background-color: #4CAF50; color: white; }
tr:nth-child(even) { background-color: #f9f9f9; }
.recommended { background-color: #e8f5e9; font-weight: bold; }
.warning { background-color: #fff3e0; }
</style>
</head>
<body>
<h1>Hosting Options Comparison</h1>
<p>Choose the right hosting for your project stage.</p>
<table>
<tr>
<th>Host Type</th>
<th>Cost</th>
<th>Control</th>
<th>Difficulty</th>
<th>Best For</th>
</tr>
<tr class="recommended">
<td>Shared Hosting</td>
<td>$3-10/month</td>
<td>Low</td>
<td>Easy</td>
<td>Small business sites, beginners</td>
</tr>
<tr>
<td>VPS</td>
<td>$5-50/month</td>
<td>High</td>
<td>Medium</td>
<td>Growing sites, developers</td>
</tr>
<tr class="warning">
<td>Free Hosting</td>
<td>$0</td>
<td>Very Low</td>
<td>Easy</td>
<td>Testing, portfolios, learning</td>
</tr>
</table>
</body>
</html>
Exercises
- Research three shared hosting providers and list their starter prices.
- Sign up for a free hosting account and note the file upload limits.
- Compare CPU and RAM specs for two VPS providers.
Homework
- Create a decision matrix for hosting providers you would recommend for an e-commerce site. Justify each choice.
- Write a 300-word blog post explaining why free hosting is not suitable for a real business.
Quiz
- Which hosting type gives you root access to the server?
- A) Shared hosting
- B) VPS
- C) Free hosting
- D) None
- Answer: B
- What is the main disadvantage of free hosting?
- A) Fast performance
- B) No ads
- C) Limited resources and uptime
- D) Full control
- Answer: C
- Which host type is best for a complete beginner?
- A) Dedicated server
- B) Shared hosting
- C) Cloud functions
- D) VPS
- Answer: B
- What does FTP stand for?
- A) File Transfer Protocol
- B) Fast Transfer Process
- C) Front-end Transfer Program
- D) File Type Protocol
- Answer: A
- Which is a free hosting provider?
- A) AWS
- B) InfinityFree
- C) DigitalOcean
- D) HostGator
- Answer: B
Lesson 2: Domain Names and DNS
- Duration: 60 minutes
- Learning objectives:
- Understand how domain names work
- Register a domain name
- Configure DNS records (A, CNAME, MX)
- Connect a domain to hosting
Instructor notes
Domains are digital addresses. Use the postal address analogy. Emphasize that domains must be registered through ICANN-accredited registrars. Show how to use WHOIS lookup.
Presentation outline
- What is a domain name?
- How DNS works (simplified)
- Domain registration process
- DNS record types: A, CNAME, MX, TXT
- Connecting domain to hosting
Demonstration
- Search for an available domain on Namecheap or GoDaddy
- Purchase a domain and review the dashboard
- Add an A record pointing to hosting IP
- Verify propagation with whatsmyDNS.net
AI prompts
- "Explain DNS resolution in simple terms for a 15-year-old. Use an analogy."
- "What DNS records are needed to point a domain to InfinityFree hosting? Show the exact values."
- "How long does DNS propagation take? What factors affect it?"
Starter code
<?php
// Check if domain resolves to this server
$domain = $_SERVER['HTTP_HOST'];
echo "Current domain: " . $domain;
if ($domain === 'localhost') {
echo " - Running locally";
} else {
echo " - Live site";
}
?>
Final code
<?php
// config.php - Environment-aware configuration
$host = $_SERVER['HTTP_HOST'];
// Define environment based on hostname
if (strpos($host, 'localhost') !== false || strpos($host, '127.0.0.1') !== false) {
define('ENV', 'development');
define('DB_HOST', 'localhost');
define('DB_NAME', 'store_dev');
define('DB_USER', 'root');
define('DB_PASS', '');
define('BASE_URL', 'http://localhost/store');
error_reporting(E_ALL);
ini_set('display_errors', 1);
} else {
define('ENV', 'production');
define('DB_HOST', 'sqlXXX.infinityfreeapp.com');
define('DB_NAME', 'epiz_12345678_store');
define('DB_USER', 'epiz_12345678');
define('DB_PASS', 'your_password_here');
define('BASE_URL', 'https://yourdomain.com');
error_reporting(0);
ini_set('display_errors', 0);
}
// Create database connection
try {
$pdo = new PDO('mysql:host=' . DB_HOST . ';dbname=' . DB_NAME, DB_USER, DB_PASS);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch(PDOException $e) {
if (ENV === 'development') {
die("Connection failed: " . $e->getMessage());
} else {
die("Database error. Please contact support.");
}
}
?>
Exercises
- Register a free domain from Freenom or purchase a cheap .xyz domain.
- Create an A record in your hosting control panel.
- Use
nslookup or dig to verify your domain resolves to the correct IP.
Homework
- Buy a domain name for your final project. Set up DNS records and connect it to your hosting.
- Research domain privacy protection. Write a paragraph explaining why it matters.
Quiz
- What does DNS stand for?
- A) Domain Name System
- B) Data Network Service
- C) Digital Name Server
- D) Domain Navigation System
- Answer: A
- Which record type maps a domain to an IP address?
- A) MX
- B) CNAME
- C) A
- D) TXT
- Answer: C
- How long can DNS propagation take?
- A) 1 second
- B) 1 minute
- C) Up to 48 hours
- D) 1 week
- Answer: C
- Which is a domain registrar?
- A) Cloudflare
- B) Namecheap
- C) InfinityFree
- D) Both A and B
- Answer: D
- What is a CNAME record used for?
- A) Map domain to IP
- B) Map subdomain to another domain
- C) Email routing
- D) Text verification
- Answer: B
Lesson 3: File Transfer with FTP
- Duration: 60 minutes
- Learning objectives:
- Install and configure an FTP client
- Upload files to a web server
- Set correct file permissions
- Troubleshoot common transfer errors
Instructor notes
FTP is still widely used despite newer tools like SFTP. FileZilla is the standard free client. Emphasize never storing passwords in plain text.
Presentation outline
- What is FTP/SFTP?
- FTP clients: FileZilla, WinSCP
- Connecting to a server
- Uploading and downloading files
- File permissions (chmod)
- Troubleshooting
Demonstration
- Install FileZilla
- Create a new site connection with SFTP credentials
- Upload index.html to public_html folder
- Change file permissions with chmod 644
AI prompts
- "What is the difference between FTP, SFTP, and FTPS? Which should a beginner use?"
- "Show me how to configure FileZilla to connect to InfinityFree hosting with SFTP."
- "What do chmod 644, 755, and 777 mean? When should each be used?"
Starter code
<?php
// file-info.php - Display file permissions info
echo "File Permission Guide\n";
echo "644 = owner read/write, group/others read\n";
echo "755 = owner read/write/execute, group/others read/execute\n";
echo "777 = everyone full access (dangerous!)\n";
?>
Final code
<?php
// deploy-check.php - Verify file permissions after upload
function checkPermissions($file) {
if (!file_exists($file)) {
return "File not found";
}
$perms = fileperms($file);
$octal = substr(sprintf('%o', $perms), -4);
$owner = ($perms & 0x0100) ? 'r' : '-';
$owner .= ($perms & 0x0080) ? 'w' : '-';
$owner .= ($perms & 0x0040) ? 'x' : '-';
$group = ($perms & 0x0020) ? 'r' : '-';
$group .= ($perms & 0x0010) ? 'w' : '-';
$group .= ($perms & 0x0008) ? 'x' : '-';
$others = ($perms & 0x0004) ? 'r' : '-';
$others .= ($perms & 0x0002) ? 'w' : '-';
$others .= ($perms & 0x0001) ? 'x' : '-';
return [
'octal' => $octal,
'string' => $owner . $group . $others,
'safe' => $octal === '0644' || $octal === '0755'
];
}
$files = ['index.php', 'config.php', 'uploads/'];
foreach ($files as $file) {
$result = checkPermissions($file);
echo "$file: " . $result['string'] . " ($result[octal])\n";
echo $result['safe'] ? "Safe permissions\n" : "Warning: Check permissions!\n";
}
?>
Exercises
- Install FileZilla and connect to your hosting account.
- Upload a test file and verify it appears in the public_html folder.
- Set file permissions to 644 and 755. Test which pages load correctly.
Homework
- Deploy your Module 12 e-commerce project to a free host. Document the steps and any errors.
- Create a deployment checklist with at least 10 items.
Quiz
- What does FTP stand for?
- A) File Transfer Protocol
- B) Fast Transfer Program
- C) File Type Protocol
- D) Front-end Transfer Process
- Answer: A
- Which FTP client is free and open source?
- A) WinSCP
- B) FileZilla
- C) Cyberduck
- D) All of the above
- Answer: D
- What does SFTP stand for?
- A) Secure File Transfer Protocol
- B) Simple File Transfer Program
- C) System File Transfer Protocol
- D) Standard File Transfer Process
- Answer: A
- What is the recommended permission for PHP files?
- A) 777
- B) 644
- C) 755
- D) 600
- Answer: B
- Where should public files be uploaded on most shared hosts?
- A) /private
- B) /public_html
- C) /root
- D) /home
- Answer: B
Lesson 4: Environment Variables and Configuration
- Duration: 60 minutes
- Learning objectives:
- Understand environment variables
- Separate development and production settings
- Store sensitive data securely
- Use .env files in PHP projects
Instructor notes
Hardcoding database credentials is a common beginner mistake. Introduce environment variables as a professional practice. Show how to use getenv() or the vlucas/phpdotenv library.
Presentation outline
- What are environment variables?
- Development vs production environments
- Storing secrets securely
- Using .env files
- PHP configuration best practices
Demonstration
- Create a
.env file for local development
- Load it with
phpdotenv in config.php
- Show how
getenv('DB_HOST') returns different values
- Test that
.env is in .gitignore
AI prompts
- "Show me how to use vlucas/phpdotenv in a PHP project. Include installation via Composer."
- "What information should never be committed to a Git repository?"
- "Create a .env.example file for a PHP MySQL e-commerce site with all necessary variables."
Starter code
<?php
// config.php - Hardcoded credentials (BAD PRACTICE)
$db_host = 'localhost';
$db_name = 'store';
$db_user = 'root';
$db_pass = 'password123';
$pdo = new PDO("mysql:host=$db_host;dbname=$db_name", $db_user, $db_pass);
?>
Final code
<?php
// config.php - Production-ready configuration
require_once 'vendor/autoload.php';
use Dotenv\Dotenv;
// Load environment variables
$dotenv = Dotenv::createImmutable(__DIR__);
$dotenv->load();
// Database configuration from environment
$host = getenv('DB_HOST') ?: 'localhost';
$dbname = getenv('DB_NAME') ?: 'store';
$username = getenv('DB_USER') ?: 'root';
$password = getenv('DB_PASS') ?: '';
$options = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => false,
];
try {
$pdo = new PDO("mysql:host=$host;dbname=$dbname;charset=utf8mb4", $username, $password, $options);
} catch(PDOException $e) {
error_log("Database connection failed: " . $e->getMessage());
if (getenv('APP_DEBUG') === 'true') {
die("Connection failed: " . $e->getMessage());
} else {
die("Database connection error. Please try again later.");
}
}
// Application settings
define('APP_NAME', getenv('APP_NAME') ?: 'My Store');
define('APP_URL', getenv('APP_URL') ?: 'http://localhost');
define('APP_DEBUG', getenv('APP_DEBUG') === 'true');
?>
# .env file - NEVER commit this to version control
APP_NAME=My Online Store
APP_URL=http://localhost
APP_DEBUG=true
DB_HOST=localhost
DB_NAME=store
DB_USER=root
DB_PASS=
# Email configuration
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_USER=your-email@gmail.com
SMTP_PASS=your-app-password
# .gitignore
vendor/
.env
uploads/
*.log
Exercises
- Create a
.env file with at least 5 variables for your project.
- Load the
.env file in PHP and print one variable to the screen.
- Add
.env to .gitignore and verify Git ignores it.
Homework
- Refactor an existing project to use environment variables instead of hardcoded values.
- Write a deployment guide that explains how to set environment variables on a live server.
Quiz
- What is an environment variable?
- A) A global JavaScript variable
- B) A dynamic value outside the application code
- C) A CSS custom property
- D) A database column
- Answer: B
- Where should you store database passwords?
- A) In config.php as plain text
- B) In a .env file
- C) In HTML comments
- D) In JavaScript variables
- Answer: B
- What should .env be added to?
- A) .gitignore
- B) composer.json
- C) index.php
- D) .htaccess
- Answer: A
- What does APP_DEBUG=true do?
- A) Deletes errors
- B) Shows detailed error messages
- C) Optimizes the database
- D) Enables HTTPS
- Answer: B
- Which function reads environment variables in PHP?
- A) $_ENV
- B) getenv()
- C) Both A and B
- D) env()
- Answer: C
Lesson 5: Going Live - Final Steps
- Duration: 90 minutes
- Learning objectives:
- Perform pre-launch testing
- Migrate a local database to production
- Configure HTTPS
- Set up monitoring and backups
- Launch a website successfully
Instructor notes
Launch day is stressful. Emphasize testing everything before going live. Use a checklist approach. Remind students that HTTPS is now mandatory for all sites.
Presentation outline
- Pre-launch checklist
- Database migration
- Enabling HTTPS with Let's Encrypt
- Backups and monitoring
- Launch and post-launch tasks
Demonstration
- Export local database with phpMyAdmin
- Import to production database
- Enable free SSL with Let's Encrypt in cPanel
- Test HTTPS redirect
- Create a simple backup script
AI prompts
- "Create a 20-item pre-launch checklist for a PHP MySQL website."
- "Show me how to export and import a MySQL database using phpMyAdmin."
- "How do I enable HTTPS on InfinityFree hosting? What are the steps?"
Starter code
<?php
// backup.php - Simple database backup
$host = 'localhost';
$user = 'root';
$pass = '';
$name = 'store';
$backup_file = 'backup_' . date('Y-m-d') . '.sql';
$command = "mysqldump --host=$host --user=$user --password=$pass $name > $backup_file";
system($command);
echo "Backup created: $backup_file";
?>
Final code
<?php
// backup.php - Production database backup script
require_once 'config.php';
function backupDatabase($host, $username, $password, $database, $output_dir = 'backups/') {
if (!is_dir($output_dir)) {
mkdir($output_dir, 0755, true);
}
$date = date('Y-m-d_H-i-s');
$output_file = $output_dir . $database . '_' . $date . '.sql.gz';
$command = sprintf(
'mysqldump --host=%s --user=%s --password=%s --single-transaction --routines --triggers %s | gzip > %s',
escapeshellarg($host),
escapeshellarg($username),
escapeshellarg($password),
escapeshellarg($database),
escapeshellarg($output_file)
);
exec($command, $output, $return_var);
if ($return_var === 0 && file_exists($output_file)) {
return [
'success' => true,
'file' => $output_file,
'size' => filesize($output_file)
];
} else {
return ['success' => false, 'error' => 'Backup failed'];
}
}
// Create backup
$result = backupDatabase(DB_HOST, DB_USER, DB_PASS, DB_NAME);
if ($result['success']) {
echo "Backup created successfully: " . $result['file'] . " (" . formatBytes($result['size']) . ")";
} else {
echo "Backup failed: " . $result['error'];
}
function formatBytes($bytes, $precision = 2) {
$units = ['B', 'KB', 'MB', 'GB'];
$bytes = max($bytes, 0);
$pow = floor(($bytes ? log($bytes) : 0) / log(1024));
$pow = min($pow, count($units) - 1);
$bytes /= pow(1024, $pow);
return round($bytes, $precision) . ' ' . $units[$pow];
}
?>
<?php
// deploy.php - Deployment helper script
require_once 'config.php';
function runMigrations($pdo) {
$sql = file_get_contents('database/schema.sql');
$pdo->exec($sql);
echo "Database schema updated successfully.\n";
}
function verifyHTTPS() {
$isHTTPS = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off')
|| $_SERVER['SERVER_PORT'] == 443;
if (!$isHTTPS) {
header('Location: https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']);
exit();
}
}
function checkRequirements() {
$requirements = [
'PHP >= 7.4' => version_compare(PHP_VERSION, '7.4.0', '>='),
'PDO Extension' => extension_loaded('pdo'),
'MySQL Support' => extension_loaded('pdo_mysql'),
'Writable uploads/' => is_writable('uploads/'),
'Config file exists' => file_exists('config.php'),
];
echo "Deployment Check:\n";
foreach ($requirements as $name => $status) {
echo $status ? "[PASS] $name\n" : "[FAIL] $name\n";
}
}
checkRequirements();
?>
Exercises
- Export your local database and import it to a remote MySQL server.
- Set up Let's Encrypt SSL on your hosting account.
- Create a database backup script and schedule it with cron.
Homework
- Deploy your final project to a live host. Complete the deployment checklist.
- Set up automated daily backups and test restoring from a backup file.
Quiz
- What is HTTPS?
- A) HyperText Transfer Protocol Secure
- B) HyperText Transfer Protocol Standard
- C) High Tech Transfer Protocol
- D) None
- Answer: A
- What does Let's Encrypt provide?
- A) Web hosting
- B) Free SSL certificates
- C) Domain registration
- D) Email hosting
- Answer: B
- What should you do before going live?
- A) Delete all test data
- B) Enable HTTPS
- C) Backup the database
- D) All of the above
- Answer: D
- What is a deployment checklist?
- A) A list of pre-launch tasks
- B) A server monitoring tool
- C) A backup schedule
- D) A cron job list
- Answer: A
- What is database migration?
- A) Moving a database to another server
- B) Deleting old records
- C) Optimizing queries
- D) Creating indexes
- Answer: A
الوحدة 15: النشر (Deployment)
الدرس 1: فهم خيارات الاستضافة
- المدة: 90 دقيقة
- أهداف التعلّم:
- مقارنة الاستضافة المشتركة، وVPS، وخيارات الاستضافة المجانية
- تحديد مزايا وعيوب كل نوع استضافة
- اختيار الاستضافة المناسبة لمشروع مبتدئ
- وضع توقعات واقعية للأداء والتكلفة
ملاحظات المدرّب
يخلط معظم المبتدئين بين أنواع الاستضافة. أكّد أن الاستضافة المشتركة هي أسهل نقطة بداية، لكن المضيفين المجانيين مثل InfinityFree لديهم قيود (إعلانات، توقف، لا وصول جذري). استخدم التشبيهات: الاستضافة المشتركة كاستئجار غرفة في منزل مشترك؛ وVPS كامتلاك مبنى سكني.
مخطط العرض التقديمي
- ما هي استضافة الويب؟
- أنواع الاستضافة: مشتركة، VPS، مخصصة، سحابية، مجانية
- مقارنة التكلفة والتحكم والصعوبة
- خيارات الاستضافة المجانية: InfinityFree و000webhost وNetlify
- اختيار المضيف المناسب لمشروعك
العرض العملي
- زُر InfinityFree.net وأنشئ حسابًا مجانيًا
- قارن ميزات لوحة التحكم مع استضافة مشتركة مدفوعة
- راجع مدير الملفات وأدوات إنشاء قاعدة البيانات
- اختبر عنوان URL لموقع مباشر
موجّهات الذكاء الاصطناعي
- "Compare shared hosting vs VPS for a beginner PHP MySQL project. Include cost, setup difficulty, and maintenance requirements."
- "List 5 free hosting providers that support PHP and MySQL. Rank them by reliability and ease of use for beginners."
- "What are the limitations of free hosting providers? How do they affect a production e-commerce website?"
الكود المبدئي
<!-- hosting-comparison.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Hosting Comparison</title>
<style>
table { border-collapse: collapse; width: 100%; }
th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
th { background-color: #f2f2f2; }
</style>
</head>
<body>
<h1>Hosting Comparison</h1>
<table>
<tr>
<th>Host Type</th>
<th>Cost</th>
<th>Control</th>
<th>Difficulty</th>
</tr>
<tr>
<td>Shared</td>
<td>$3-10/month</td>
<td>Low</td>
<td>Easy</td>
</tr>
<tr>
<td>VPS</td>
<td>$5-20/month</td>
<td>High</td>
<td>Medium</td>
</tr>
<tr>
<td>Free</td>
<td>$0</td>
<td>Very Low</td>
<td>Easy</td>
</tr>
</table>
</body>
</html>
الكود النهائي
<!-- hosting-comparison.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Hosting Comparison</title>
<style>
body { font-family: Arial, sans-serif; max-width: 1000px; margin: 0 auto; padding: 20px; }
table { border-collapse: collapse; width: 100%; margin-top: 20px; }
th, td { border: 1px solid #ddd; padding: 12px; text-align: left; }
th { background-color: #4CAF50; color: white; }
tr:nth-child(even) { background-color: #f9f9f9; }
.recommended { background-color: #e8f5e9; font-weight: bold; }
.warning { background-color: #fff3e0; }
</style>
</head>
<body>
<h1>Hosting Options Comparison</h1>
<p>Choose the right hosting for your project stage.</p>
<table>
<tr>
<th>Host Type</th>
<th>Cost</th>
<th>Control</th>
<th>Difficulty</th>
<th>Best For</th>
</tr>
<tr class="recommended">
<td>Shared Hosting</td>
<td>$3-10/month</td>
<td>Low</td>
<td>Easy</td>
<td>Small business sites, beginners</td>
</tr>
<tr>
<td>VPS</td>
<td>$5-50/month</td>
<td>High</td>
<td>Medium</td>
<td>Growing sites, developers</td>
</tr>
<tr class="warning">
<td>Free Hosting</td>
<td>$0</td>
<td>Very Low</td>
<td>Easy</td>
<td>Testing, portfolios, learning</td>
</tr>
</table>
</body>
</html>
تمارين
- ابحث في ثلاثة مزوّدي استضافة مشتركة واذكر أسعارهم المبدئية.
- سجّل في حساب استضافة مجاني ودوّن حدود رفع الملفات.
- قارن مواصفات المعالج والذاكرة لمزوّدَي VPS.
الواجب المنزلي
- أنشئ مصفوفة قرار لمزوّدي الاستضافة الذين توصي بهم لموقع تجارة إلكترونية. برّر كل اختيار.
- اكتب تدوينة من 300 كلمة تشرح لماذا لا تصلح الاستضافة المجانية لعمل تجاري حقيقي.
اختبار قصير
- أي نوع استضافة يمنحك وصولًا جذريًا (root) إلى الخادم؟
- أ) الاستضافة المشتركة
- ب) VPS
- ج) الاستضافة المجانية
- د) لا شيء
- الإجابة: ب
- ما العيب الرئيسي للاستضافة المجانية؟
- أ) أداء سريع
- ب) بلا إعلانات
- ج) موارد محدودة ووقت تشغيل محدود
- د) تحكم كامل
- الإجابة: ج
- أي نوع مضيف هو الأفضل للمبتدئ التام؟
- أ) خادم مخصص
- ب) الاستضافة المشتركة
- ج) الدوال السحابية
- د) VPS
- الإجابة: ب
- ماذا تعني FTP؟
- أ) File Transfer Protocol
- ب) Fast Transfer Process
- ج) Front-end Transfer Program
- د) File Type Protocol
- الإجابة: أ
- أيٌّ مزوّد استضافة مجاني؟
- أ) AWS
- ب) InfinityFree
- ج) DigitalOcean
- د) HostGator
- الإجابة: ب
الدرس 2: أسماء النطاقات وDNS
- المدة: 60 دقيقة
- أهداف التعلّم:
- فهم كيفية عمل أسماء النطاقات
- تسجيل اسم نطاق
- تهيئة سجلات DNS (A، CNAME، MX)
- ربط نطاق بالاستضافة
ملاحظات المدرّب
النطاقات عناوين رقمية. استخدم تشبيه العنوان البريدي. أكّد أن النطاقات يجب تسجيلها عبر مسجّلين معتمدين من ICANN. اعرض كيفية استخدام بحث WHOIS.
مخطط العرض التقديمي
- ما اسم النطاق؟
- كيف يعمل DNS (مبسّطًا)
- عملية تسجيل النطاق
- أنواع سجلات DNS: A، CNAME، MX، TXT
- ربط النطاق بالاستضافة
العرض العملي
- ابحث عن نطاق متاح على Namecheap أو GoDaddy
- اشترِ نطاقًا وراجع لوحة التحكم
- أضِف سجل A يشير إلى عنوان IP للاستضافة
- تحقق من الانتشار عبر whatsmyDNS.net
موجّهات الذكاء الاصطناعي
- "Explain DNS resolution in simple terms for a 15-year-old. Use an analogy."
- "What DNS records are needed to point a domain to InfinityFree hosting? Show the exact values."
- "How long does DNS propagation take? What factors affect it?"
الكود المبدئي
<?php
// Check if domain resolves to this server
$domain = $_SERVER['HTTP_HOST'];
echo "Current domain: " . $domain;
if ($domain === 'localhost') {
echo " - Running locally";
} else {
echo " - Live site";
}
?>
الكود النهائي
<?php
// config.php - Environment-aware configuration
$host = $_SERVER['HTTP_HOST'];
// Define environment based on hostname
if (strpos($host, 'localhost') !== false || strpos($host, '127.0.0.1') !== false) {
define('ENV', 'development');
define('DB_HOST', 'localhost');
define('DB_NAME', 'store_dev');
define('DB_USER', 'root');
define('DB_PASS', '');
define('BASE_URL', 'http://localhost/store');
error_reporting(E_ALL);
ini_set('display_errors', 1);
} else {
define('ENV', 'production');
define('DB_HOST', 'sqlXXX.infinityfreeapp.com');
define('DB_NAME', 'epiz_12345678_store');
define('DB_USER', 'epiz_12345678');
define('DB_PASS', 'your_password_here');
define('BASE_URL', 'https://yourdomain.com');
error_reporting(0);
ini_set('display_errors', 0);
}
// Create database connection
try {
$pdo = new PDO('mysql:host=' . DB_HOST . ';dbname=' . DB_NAME, DB_USER, DB_PASS);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch(PDOException $e) {
if (ENV === 'development') {
die("Connection failed: " . $e->getMessage());
} else {
die("Database error. Please contact support.");
}
}
?>
تمارين
- سجّل نطاقًا مجانيًا من Freenom أو اشترِ نطاق .xyz رخيصًا.
- أنشئ سجل A في لوحة تحكم الاستضافة الخاصة بك.
- استخدم
nslookup أو dig للتحقق من أن نطاقك يشير إلى عنوان IP الصحيح.
الواجب المنزلي
- اشترِ اسم نطاق لمشروعك النهائي. اضبط سجلات DNS واربطه باستضافتك.
- ابحث في حماية خصوصية النطاق. اكتب فقرة تشرح أهميتها.
اختبار قصير
- ماذا تعني DNS؟
- أ) Domain Name System
- ب) Data Network Service
- ج) Digital Name Server
- د) Domain Navigation System
- الإجابة: أ
- أي نوع سجل يربط نطاقًا بعنوان IP؟
- أ) MX
- ب) CNAME
- ج) A
- د) TXT
- الإجابة: ج
- كم قد يستغرق انتشار DNS؟
- أ) ثانية واحدة
- ب) دقيقة واحدة
- ج) حتى 48 ساعة
- د) أسبوع واحد
- الإجابة: ج
- أيٌّ مسجّل نطاقات؟
- أ) Cloudflare
- ب) Namecheap
- ج) InfinityFree
- د) كلٌّ من أ وب
- الإجابة: د
- لماذا يُستخدم سجل CNAME؟
- أ) ربط نطاق بعنوان IP
- ب) ربط نطاق فرعي بنطاق آخر
- ج) توجيه البريد الإلكتروني
- د) التحقق النصّي
- الإجابة: ب
الدرس 3: نقل الملفات باستخدام FTP
- المدة: 60 دقيقة
- أهداف التعلّم:
- تثبيت وتهيئة عميل FTP
- رفع الملفات إلى خادم ويب
- ضبط أذونات الملفات الصحيحة
- حل أخطاء النقل الشائعة
ملاحظات المدرّب
لا يزال FTP مستخدمًا على نطاق واسع رغم الأدوات الأحدث مثل SFTP. FileZilla هو العميل المجاني القياسي. أكّد على عدم تخزين كلمات المرور كنص عادي أبدًا.
مخطط العرض التقديمي
- ما FTP/SFTP؟
- عملاء FTP: FileZilla، WinSCP
- الاتصال بخادم
- رفع الملفات وتنزيلها
- أذونات الملفات (chmod)
- حل المشكلات
العرض العملي
- ثبّت FileZilla
- أنشئ اتصال موقع جديد ببيانات اعتماد SFTP
- ارفع index.html إلى مجلد public_html
- غيّر أذونات الملف بـ chmod 644
موجّهات الذكاء الاصطناعي
- "What is the difference between FTP, SFTP, and FTPS? Which should a beginner use?"
- "Show me how to configure FileZilla to connect to InfinityFree hosting with SFTP."
- "What do chmod 644, 755, and 777 mean? When should each be used?"
الكود المبدئي
<?php
// file-info.php - Display file permissions info
echo "File Permission Guide\n";
echo "644 = owner read/write, group/others read\n";
echo "755 = owner read/write/execute, group/others read/execute\n";
echo "777 = everyone full access (dangerous!)\n";
?>
الكود النهائي
<?php
// deploy-check.php - Verify file permissions after upload
function checkPermissions($file) {
if (!file_exists($file)) {
return "File not found";
}
$perms = fileperms($file);
$octal = substr(sprintf('%o', $perms), -4);
$owner = ($perms & 0x0100) ? 'r' : '-';
$owner .= ($perms & 0x0080) ? 'w' : '-';
$owner .= ($perms & 0x0040) ? 'x' : '-';
$group = ($perms & 0x0020) ? 'r' : '-';
$group .= ($perms & 0x0010) ? 'w' : '-';
$group .= ($perms & 0x0008) ? 'x' : '-';
$others = ($perms & 0x0004) ? 'r' : '-';
$others .= ($perms & 0x0002) ? 'w' : '-';
$others .= ($perms & 0x0001) ? 'x' : '-';
return [
'octal' => $octal,
'string' => $owner . $group . $others,
'safe' => $octal === '0644' || $octal === '0755'
];
}
$files = ['index.php', 'config.php', 'uploads/'];
foreach ($files as $file) {
$result = checkPermissions($file);
echo "$file: " . $result['string'] . " ($result[octal])\n";
echo $result['safe'] ? "Safe permissions\n" : "Warning: Check permissions!\n";
}
?>
تمارين
- ثبّت FileZilla واتصل بحساب استضافتك.
- ارفع ملف اختبار وتأكد من ظهوره في مجلد public_html.
- اضبط أذونات الملفات على 644 و755. اختبر أي صفحات تُحمّل بشكل صحيح.
الواجب المنزلي
- انشر مشروع التجارة الإلكترونية من الوحدة 12 على مضيف مجاني. وثّق الخطوات وأي أخطاء.
- أنشئ قائمة تحقق للنشر تضم 10 عناصر على الأقل.
اختبار قصير
- ماذا تعني FTP؟
- أ) File Transfer Protocol
- ب) Fast Transfer Program
- ج) File Type Protocol
- د) Front-end Transfer Process
- الإجابة: أ
- أي عميل FTP مجاني ومفتوح المصدر؟
- أ) WinSCP
- ب) FileZilla
- ج) Cyberduck
- د) كل ما سبق
- الإجابة: د
- ماذا تعني SFTP؟
- أ) Secure File Transfer Protocol
- ب) Simple File Transfer Program
- ج) System File Transfer Protocol
- د) Standard File Transfer Process
- الإجابة: أ
- ما الإذن الموصى به لملفات PHP؟
- أ) 777
- ب) 644
- ج) 755
- د) 600
- الإجابة: ب
- أين ينبغي رفع الملفات العامة على معظم المضيفين المشتركين؟
- أ) /private
- ب) /public_html
- ج) /root
- د) /home
- الإجابة: ب
الدرس 4: متغيرات البيئة والتهيئة
- المدة: 60 دقيقة
- أهداف التعلّم:
- فهم متغيرات البيئة
- الفصل بين إعدادات التطوير والإنتاج
- تخزين البيانات الحساسة بأمان
- استخدام ملفات .env في مشاريع PHP
ملاحظات المدرّب
تضمين بيانات اعتماد قاعدة البيانات مباشرة في الكود خطأ شائع لدى المبتدئين. قدّم متغيرات البيئة كممارسة احترافية. اعرض كيفية استخدام getenv() أو مكتبة vlucas/phpdotenv.
مخطط العرض التقديمي
- ما متغيرات البيئة؟
- بيئات التطوير مقابل الإنتاج
- تخزين الأسرار بأمان
- استخدام ملفات .env
- أفضل ممارسات تهيئة PHP
العرض العملي
- أنشئ ملف
.env للتطوير المحلي
- حمّله باستخدام
phpdotenv في config.php
- أظهر كيف يُرجع
getenv('DB_HOST') قيمًا مختلفة
- تأكد من وجود
.env في .gitignore
موجّهات الذكاء الاصطناعي
- "Show me how to use vlucas/phpdotenv in a PHP project. Include installation via Composer."
- "What information should never be committed to a Git repository?"
- "Create a .env.example file for a PHP MySQL e-commerce site with all necessary variables."
الكود المبدئي
<?php
// config.php - Hardcoded credentials (BAD PRACTICE)
$db_host = 'localhost';
$db_name = 'store';
$db_user = 'root';
$db_pass = 'password123';
$pdo = new PDO("mysql:host=$db_host;dbname=$db_name", $db_user, $db_pass);
?>
الكود النهائي
<?php
// config.php - Production-ready configuration
require_once 'vendor/autoload.php';
use Dotenv\Dotenv;
// Load environment variables
$dotenv = Dotenv::createImmutable(__DIR__);
$dotenv->load();
// Database configuration from environment
$host = getenv('DB_HOST') ?: 'localhost';
$dbname = getenv('DB_NAME') ?: 'store';
$username = getenv('DB_USER') ?: 'root';
$password = getenv('DB_PASS') ?: '';
$options = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => false,
];
try {
$pdo = new PDO("mysql:host=$host;dbname=$dbname;charset=utf8mb4", $username, $password, $options);
} catch(PDOException $e) {
error_log("Database connection failed: " . $e->getMessage());
if (getenv('APP_DEBUG') === 'true') {
die("Connection failed: " . $e->getMessage());
} else {
die("Database connection error. Please try again later.");
}
}
// Application settings
define('APP_NAME', getenv('APP_NAME') ?: 'My Store');
define('APP_URL', getenv('APP_URL') ?: 'http://localhost');
define('APP_DEBUG', getenv('APP_DEBUG') === 'true');
?>
# .env file - NEVER commit this to version control
APP_NAME=My Online Store
APP_URL=http://localhost
APP_DEBUG=true
DB_HOST=localhost
DB_NAME=store
DB_USER=root
DB_PASS=
# Email configuration
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_USER=your-email@gmail.com
SMTP_PASS=your-app-password
# .gitignore
vendor/
.env
uploads/
*.log
تمارين
- أنشئ ملف
.env يحتوي على 5 متغيرات على الأقل لمشروعك.
- حمّل ملف
.env في PHP واطبع متغيرًا واحدًا على الشاشة.
- أضِف
.env إلى .gitignore وتأكد من أن Git يتجاهله.
الواجب المنزلي
- أعِد هيكلة مشروع قائم لاستخدام متغيرات البيئة بدلًا من القيم المضمّنة في الكود.
- اكتب دليل نشر يشرح كيفية ضبط متغيرات البيئة على خادم مباشر.
اختبار قصير
- ما متغيّر البيئة؟
- أ) متغيّر JavaScript عام
- ب) قيمة ديناميكية خارج كود التطبيق
- ج) خاصية CSS مخصصة
- د) عمود في قاعدة بيانات
- الإجابة: ب
- أين ينبغي تخزين كلمات مرور قاعدة البيانات؟
- أ) في config.php كنص عادي
- ب) في ملف .env
- ج) في تعليقات HTML
- د) في متغيرات JavaScript
- الإجابة: ب
- إلى ماذا ينبغي إضافة .env؟
- أ) .gitignore
- ب) composer.json
- ج) index.php
- د) .htaccess
- الإجابة: أ
- ماذا يفعل APP_DEBUG=true؟
- أ) يحذف الأخطاء
- ب) يعرض رسائل أخطاء مفصّلة
- ج) يُحسّن قاعدة البيانات
- د) يُفعّل HTTPS
- الإجابة: ب
- أي دالة تقرأ متغيرات البيئة في PHP؟
- أ) $_ENV
- ب) getenv()
- ج) كلٌّ من أ وب
- د) env()
- الإجابة: ج
الدرس 5: الانطلاق للبثّ المباشر - الخطوات النهائية
- المدة: 90 دقيقة
- أهداف التعلّم:
- إجراء اختبار ما قبل الإطلاق
- ترحيل قاعدة بيانات محلية إلى الإنتاج
- تهيئة HTTPS
- إعداد المراقبة والنسخ الاحتياطي
- إطلاق موقع بنجاح
ملاحظات المدرّب
يوم الإطلاق مرهق. أكّد على اختبار كل شيء قبل البثّ المباشر. استخدم نهج قائمة التحقق. ذكّر الطلاب بأن HTTPS أصبح إلزاميًا الآن لجميع المواقع.
مخطط العرض التقديمي
- قائمة تحقق ما قبل الإطلاق
- ترحيل قاعدة البيانات
- تفعيل HTTPS باستخدام Let's Encrypt
- النسخ الاحتياطي والمراقبة
- مهام الإطلاق وما بعده
العرض العملي
- صدّر قاعدة البيانات المحلية باستخدام phpMyAdmin
- استوردها إلى قاعدة بيانات الإنتاج
- فعّل SSL المجاني بـ Let's Encrypt في cPanel
- اختبر إعادة توجيه HTTPS
- أنشئ سكربت نسخ احتياطي بسيط
موجّهات الذكاء الاصطناعي
- "Create a 20-item pre-launch checklist for a PHP MySQL website."
- "Show me how to export and import a MySQL database using phpMyAdmin."
- "How do I enable HTTPS on InfinityFree hosting? What are the steps?"
الكود المبدئي
<?php
// backup.php - Simple database backup
$host = 'localhost';
$user = 'root';
$pass = '';
$name = 'store';
$backup_file = 'backup_' . date('Y-m-d') . '.sql';
$command = "mysqldump --host=$host --user=$user --password=$pass $name > $backup_file";
system($command);
echo "Backup created: $backup_file";
?>
الكود النهائي
<?php
// backup.php - Production database backup script
require_once 'config.php';
function backupDatabase($host, $username, $password, $database, $output_dir = 'backups/') {
if (!is_dir($output_dir)) {
mkdir($output_dir, 0755, true);
}
$date = date('Y-m-d_H-i-s');
$output_file = $output_dir . $database . '_' . $date . '.sql.gz';
$command = sprintf(
'mysqldump --host=%s --user=%s --password=%s --single-transaction --routines --triggers %s | gzip > %s',
escapeshellarg($host),
escapeshellarg($username),
escapeshellarg($password),
escapeshellarg($database),
escapeshellarg($output_file)
);
exec($command, $output, $return_var);
if ($return_var === 0 && file_exists($output_file)) {
return [
'success' => true,
'file' => $output_file,
'size' => filesize($output_file)
];
} else {
return ['success' => false, 'error' => 'Backup failed'];
}
}
// Create backup
$result = backupDatabase(DB_HOST, DB_USER, DB_PASS, DB_NAME);
if ($result['success']) {
echo "Backup created successfully: " . $result['file'] . " (" . formatBytes($result['size']) . ")";
} else {
echo "Backup failed: " . $result['error'];
}
function formatBytes($bytes, $precision = 2) {
$units = ['B', 'KB', 'MB', 'GB'];
$bytes = max($bytes, 0);
$pow = floor(($bytes ? log($bytes) : 0) / log(1024));
$pow = min($pow, count($units) - 1);
$bytes /= pow(1024, $pow);
return round($bytes, $precision) . ' ' . $units[$pow];
}
?>
<?php
// deploy.php - Deployment helper script
require_once 'config.php';
function runMigrations($pdo) {
$sql = file_get_contents('database/schema.sql');
$pdo->exec($sql);
echo "Database schema updated successfully.\n";
}
function verifyHTTPS() {
$isHTTPS = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off')
|| $_SERVER['SERVER_PORT'] == 443;
if (!$isHTTPS) {
header('Location: https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']);
exit();
}
}
function checkRequirements() {
$requirements = [
'PHP >= 7.4' => version_compare(PHP_VERSION, '7.4.0', '>='),
'PDO Extension' => extension_loaded('pdo'),
'MySQL Support' => extension_loaded('pdo_mysql'),
'Writable uploads/' => is_writable('uploads/'),
'Config file exists' => file_exists('config.php'),
];
echo "Deployment Check:\n";
foreach ($requirements as $name => $status) {
echo $status ? "[PASS] $name\n" : "[FAIL] $name\n";
}
}
checkRequirements();
?>
تمارين
- صدّر قاعدة البيانات المحلية واستوردها إلى خادم MySQL بعيد.
- أعدّ SSL من Let's Encrypt على حساب استضافتك.
- أنشئ سكربت نسخ احتياطي لقاعدة البيانات وجدوِله باستخدام cron.
الواجب المنزلي
- انشر مشروعك النهائي على مضيف مباشر. أكمِل قائمة تحقق النشر.
- أعدّ نسخًا احتياطية يومية آلية واختبر الاستعادة من ملف نسخة احتياطية.
اختبار قصير
- ما HTTPS؟
- أ) HyperText Transfer Protocol Secure
- ب) HyperText Transfer Protocol Standard
- ج) High Tech Transfer Protocol
- د) لا شيء
- الإجابة: أ
- ماذا يوفّر Let's Encrypt؟
- أ) استضافة ويب
- ب) شهادات SSL مجانية
- ج) تسجيل نطاقات
- د) استضافة بريد إلكتروني
- الإجابة: ب
- ماذا ينبغي أن تفعل قبل البثّ المباشر؟
- أ) حذف كل بيانات الاختبار
- ب) تفعيل HTTPS
- ج) نسخ قاعدة البيانات احتياطيًا
- د) كل ما سبق
- الإجابة: د
- ما قائمة تحقق النشر؟
- أ) قائمة بمهام ما قبل الإطلاق
- ب) أداة مراقبة خادم
- ج) جدول نسخ احتياطي
- د) قائمة مهام cron
- الإجابة: أ
- ما ترحيل قاعدة البيانات؟
- أ) نقل قاعدة بيانات إلى خادم آخر
- ب) حذف السجلات القديمة
- ج) تحسين الاستعلامات
- د) إنشاء الفهارس
- الإجابة: أ