در این دوره خود زبان PHP را از اولین echo تا شیءگرایی، enum و استثناها یاد میگیرید. هر کد روی PHP 8.2 اجرا میشود و خروجی آن همان لحظه بررسی میشود.
<?php
$sales = [
['city' => 'Tehran', 'product' => 'Laptop', 'amount' => 3],
['city' => 'Tabriz', 'product' => 'Phone', 'amount' => 5],
['city' => 'Tehran', 'product' => 'Phone', 'amount' => 2],
['city' => 'Shiraz', 'product' => 'Laptop', 'amount' => 1],
['city' => 'Tabriz', 'product' => 'Laptop', 'amount' => 2],
];
$prices = ['Laptop' => 42_000_000, 'Phone' => 18_500_000];
// به هر ردیف مبلغ فروش را اضافه میکنیم
$rows = array_map(
fn($s) => $s + ['total' => $s['amount'] * $prices[$s['product']]],
$sales
);
// جمع فروش هر شهر با array_reduce
$byCity = array_reduce($rows, function ($acc, $r) {
$acc[$r['city']] = ($acc[$r['city']] ?? 0) + $r['total'];
return $acc;
}, []);
arsort($byCity); // از بیشترین به کمترین، با حفظ کلیدها
foreach ($byCity as $city => $total) {
echo str_pad($city, 8), str_pad(number_format($total), 14, ' ', STR_PAD_LEFT), "\n";
}
echo str_repeat('-', 22), "\n";
echo str_pad('Total', 8), str_pad(number_format(array_sum($byCity)), 14, ' ', STR_PAD_LEFT), "\n";
Tabriz 176,500,000 Tehran 163,000,000 Shiraz 42,000,000 ---------------------- Total 381,500,000
از فهرست فروشها، مبلغ هر ردیف حساب میشود و فروش هر شهر جمع میخورد. نتیجه از بیشترین به کمترین مرتب و با جداکنندهٔ هزارگان چاپ میشود. نمونههای دیگر
تمرکز دوره روی خود زبان است، با بیشترین درس برای آرایهها و شیءگرایی.
با echo خروجی میسازید و نوعهای PHP، تبدیل نوع و ثابتها را میشناسید.
فرق == و === را با جدول مقایسه یاد میگیرید و از عملگر ?? و عملگر فضاپیما استفاده میکنید.
با درونیابی، heredoc، sprintf و explode متن میسازید، میفهمید چرا strlen برای فارسی بایت میشمارد و اعشار را درست گرد و مقایسه میکنید.
برنامه را با if، switch، match و حلقههای for، foreach و while هدایت میکنید.
آرایهٔ اندیسی و انجمنی میسازید و با array_map، array_filter، array_reduce، usort و توابع مجموعهای گزارش میگیرید.
تابع نوعدار با مقدار پیشفرض، آرگومان نامدار و variadic مینویسید و از بستار، تابع پیکانی و callable استفاده میکنید.
کلاس، ارتقای سازنده، وراثت، کلاس انتزاعی، interface، trait، namespace و متدهای جادویی را به کار میبرید.
حالتها را با enum و کلاس readonly مدل میکنید، خطا را با استثنای سفارشی مدیریت میکنید و با yield داده را در لحظهٔ نیاز میسازید.
متن فارسی را با preg_match و پرچم u جستوجو میکنید، JSON میسازید و میخوانید، با DateTime کار میکنید و خط لولهٔ تابعی مینویسید.
دامهای isset، empty و in_array را میشناسید و یک موتور محاسبهٔ عبارت و گزارش و یک سامانهٔ بانکی شیءگرا را از صفر میسازید.
این پنج نمونه را برای همین صفحه نوشتهایم. هر کدام روی همان PHP 8.2 درسها اجرا شده و خروجی کنارش همان چیزی است که چاپ میکند.
از فهرست فروشها، مبلغ هر ردیف حساب میشود و فروش هر شهر جمع میخورد. نتیجه از بیشترین به کمترین مرتب و با جداکنندهٔ هزارگان چاپ میشود.
<?php
$sales = [
['city' => 'Tehran', 'product' => 'Laptop', 'amount' => 3],
['city' => 'Tabriz', 'product' => 'Phone', 'amount' => 5],
['city' => 'Tehran', 'product' => 'Phone', 'amount' => 2],
['city' => 'Shiraz', 'product' => 'Laptop', 'amount' => 1],
['city' => 'Tabriz', 'product' => 'Laptop', 'amount' => 2],
];
$prices = ['Laptop' => 42_000_000, 'Phone' => 18_500_000];
// به هر ردیف مبلغ فروش را اضافه میکنیم
$rows = array_map(
fn($s) => $s + ['total' => $s['amount'] * $prices[$s['product']]],
$sales
);
// جمع فروش هر شهر با array_reduce
$byCity = array_reduce($rows, function ($acc, $r) {
$acc[$r['city']] = ($acc[$r['city']] ?? 0) + $r['total'];
return $acc;
}, []);
arsort($byCity); // از بیشترین به کمترین، با حفظ کلیدها
foreach ($byCity as $city => $total) {
echo str_pad($city, 8), str_pad(number_format($total), 14, ' ', STR_PAD_LEFT), "\n";
}
echo str_repeat('-', 22), "\n";
echo str_pad('Total', 8), str_pad(number_format(array_sum($byCity)), 14, ' ', STR_PAD_LEFT), "\n";
Tabriz 176,500,000 Tehran 163,000,000 Shiraz 42,000,000 ---------------------- Total 381,500,000
وضعیتهای مجاز یک سفارش در یک enum تعریف شدهاند و هر کدام برچسب و قاعدهٔ لغو خودش را دارد. برای مقداری که در enum نیست، tryFrom بهجای خطا null برمیگرداند.
<?php
// enum با مقدار رشتهای: فقط همین چهار حالت معتبر است
enum Status: string
{
case Pending = 'pending';
case Paid = 'paid';
case Shipped = 'shipped';
case Cancelled = 'cancelled';
public function label(): string
{
// match مقدار برمیگرداند و مقایسهاش سختگیر (===) است
return match ($this) {
Status::Pending => 'waiting for payment',
Status::Paid => 'paid, packing',
Status::Shipped => 'on the way',
Status::Cancelled => 'cancelled',
};
}
public function canCancel(): bool
{
return in_array($this, [Status::Pending, Status::Paid], true);
}
}
foreach (['paid', 'shipped', 'refunded', 'pending'] as $raw) {
$status = Status::tryFrom($raw); // مقدار نامعتبر null میدهد، نه خطا
if ($status === null) {
echo str_pad($raw, 10), "unknown status\n";
continue;
}
$cancel = $status->canCancel() ? 'yes' : 'no';
echo str_pad($raw, 10), str_pad($status->label(), 21), "cancel: $cancel\n";
}
paid paid, packing cancel: yes shipped on the way cancel: no refunded unknown status pending waiting for payment cancel: yes
کلاس Account با ارتقای سازنده در چند خط تعریف شده است. برداشت بیش از موجودی استثنای سفارشی پرتاب میکند و نام صاحب حساب بعد از ساخت عوض نمیشود.
<?php
final class InsufficientFunds extends RuntimeException {}
final class Account
{
// ارتقای سازنده: پراپرتیها همینجا تعریف و مقداردهی میشوند
public function __construct(
public readonly string $owner,
private int $balance = 0,
) {}
public function deposit(int $amount): static
{
$this->balance += $amount;
return $this;
}
public function withdraw(int $amount): static
{
if ($amount > $this->balance) {
throw new InsufficientFunds("{$this->owner} has only {$this->balance}");
}
$this->balance -= $amount;
return $this;
}
public function balance(): int
{
return $this->balance;
}
}
$acc = new Account('Sara');
$acc->deposit(500)->withdraw(120)->deposit(80);
echo "{$acc->owner}: {$acc->balance()}\n";
try {
$acc->withdraw(1000);
} catch (InsufficientFunds $e) {
echo 'refused: ', $e->getMessage(), "\n";
}
try {
$acc->owner = 'Reza'; // readonly است و بعد از ساخت عوض نمیشود
} catch (Error $e) {
echo get_class($e), ': ', $e->getMessage(), "\n";
}
Sara: 460 refused: Sara has only 460 Error: Cannot modify readonly property Account::$owner
ارقام فارسی متن به لاتین تبدیل میشوند تا یک الگو هر دو نوع شماره را بگیرد. بعد شمارههای موبایل پیدا و پوشانده میشوند و هشتگهای فارسی و انگلیسی جدا میشوند.
<?php
$text = 'تماس: ۰۹۱۲۳۴۵۶۷۸۹ یا 09351112233. #برنامه_نویسی را با #PHP و #پی_اچ_پی دنبال کنید.';
// ارقام فارسی را به لاتین برمیگردانیم تا الگو هر دو را بگیرد
$normal = strtr($text, array_combine(
['۰', '۱', '۲', '۳', '۴', '۵', '۶', '۷', '۸', '۹'],
range(0, 9)
));
// پرچم u یعنی الگو و متن UTF-8 هستند؛ بدون آن هر حرف فارسی چند تکه میشود
preg_match_all('/09\d{9}/u', $normal, $phones);
preg_match_all('/#[\p{L}\p{N}_]+/u', $normal, $tags);
foreach ($phones[0] as $p) {
echo 'phone: ', preg_replace('/(?<=^\d{4})\d{4}/', '****', $p), "\n";
}
echo 'tags: ', implode(' ', $tags[0]), "\n";
phone: 0912****789 phone: 0935****233 tags: #برنامه_نویسی #PHP #پی_اچ_پی
json_encode حروف فارسی را بهطور پیشفرض به کدهایی مثل \u0633 تبدیل میکند. با دو پرچم، فارسی همانطور که هست میماند و خروجی مرتب چاپ میشود.
<?php
$student = ['name' => 'سارا', 'course' => 'PHP', 'scores' => [18, 19.5]];
// پیشفرض: حروف فارسی به کدهای \u تبدیل میشوند
echo json_encode($student), "\n";
// با این دو پرچم، فارسی همانطور که هست میماند و خروجی مرتب چاپ میشود
echo json_encode($student, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT), "\n";
// برگرداندن JSON به آرایه
$back = json_decode('{"name":"رضا","scores":[17,20]}', true);
echo 'average: ', array_sum($back['scores']) / count($back['scores']), "\n";
{"name":"\u0633\u0627\u0631\u0627","course":"PHP","scores":[18,19.5]}
{
"name": "سارا",
"course": "PHP",
"scores": [
18,
19.5
]
}
average: 18.5این دوره از ابتدا سبک امروزی PHP را یاد میدهد. ستون اول همان چیزی است که در کدهای قدیمی میبینید.
| موضوع | کد قدیمی PHP | PHP 8.2 در این دوره |
|---|---|---|
| انتخاب بین چند حالت | switch، که اگر break جا بماند به حالت بعد میرود | match، که مقدار برمیگرداند و با === مقایسه میکند |
| مجموعهٔ ثابتی از حالتها | چند ثابت کلاس | enum با from و tryFrom |
| سازندهٔ کلاس | تعریف هر پراپرتی و انتساب جداگانه در سازنده | ارتقای سازنده در چند خط |
| مقدار تغییرناپذیر | فقط با قرار میان برنامهنویسها | پراپرتی و کلاس readonly |
| مقداری که ممکن است null باشد | چند if تودرتو | عملگر ?-> |
| نوع پارامتر و خروجی | اختیاری و محدود | نوعهای union، mixed، never و DNF |
هر درس یک مفهوم را با مثال توضیح میدهد و یک کار مشخص از شما میخواهد.
با دکمهٔ اجرا، کد شما روی PHP 8.2 اجرا میشود و خروجی یا پیام خطا را همانجا میبینید.
دکمهٔ بررسی، خروجی کد را با جواب درست مقایسه میکند. اگر گیر کردید، راهنمای همان تمرین قدمبهقدم کمکتان میکند.
۲۴ سرفصل، ۱۶۸ درس، ۱۴۰ تمرین
درسهای اول رایگان است و برای شروع پرداختی لازم نیست. هر وقت خواستید ادامه دهید، همین دوره را بخرید یا با اشتراک پرو همهٔ دورهها را باز کنید.
۱۲ درس ابتدایی رایگان است. برای ادامه، اشتراک بگیرید یا دوره را بخرید.
بدون نیاز به پرداخت مبلغی برای شروع
اگر میخواهید برنامهنویسی را با زبانی شروع کنید که در وب بسیار به کار میرود.
اگر تا امروز کد PHP را از جایی کپی کردهاید و میخواهید خود زبان را درست یاد بگیرید.
اگر میخواهید کدی را که هر روز با آن کار میکنید عمیقتر بفهمید.
پیشنیاز: یک رایانه و یک مرورگر.
اولین برنامهٔ PHP خود را همین امروز در مرورگر اجرا کنید. شروع رایگان است و در کمتر از دو دقیقه وارد محیط یادگیری میشوید.