Forwarded from ابر ویراک
ویراک کلود | تجربهی ابری بدون محدودیت ☁️🚀
🎁 ۲۰٪ شارژ هدیه روی اولین واریزی
مزیتهایی که واقعاً فرق میسازن:
⚡️ پهنای باند 980 مگ
🌐با IP مازاد
⏱️ راهاندازی فوری
💳 پرداخت ساعتی
🛡 پشتیبانی ۲۴/۷
💬 هر سوالی داشتی، تیم ما کنارتـه
✅ مناسب استارتاپها، تیمهای فنی، تا سازمانهای بزرگ
همین الان شروع کن و با حداکثر منابع، سریعتر رشد کن 👇🏻
📞 تماس سریع: 02191555530
🔗 https://virakcloud.com
🎁 ۲۰٪ شارژ هدیه روی اولین واریزی
مزیتهایی که واقعاً فرق میسازن:
⚡️ پهنای باند 980 مگ
🌐با IP مازاد
⏱️ راهاندازی فوری
💳 پرداخت ساعتی
🛡 پشتیبانی ۲۴/۷
💬 هر سوالی داشتی، تیم ما کنارتـه
✅ مناسب استارتاپها، تیمهای فنی، تا سازمانهای بزرگ
همین الان شروع کن و با حداکثر منابع، سریعتر رشد کن 👇🏻
📞 تماس سریع: 02191555530
🔗 https://virakcloud.com
📌 سوال برای توسعهدهندگان PHP
خروجی اجرای کد زیر در PHP چیست؟
به رفتار reference در
🔖 #PHP #پی_اچ_پی
👤 Developix
💎 Channel: @DevelopixPHP
خروجی اجرای کد زیر در PHP چیست؟
به رفتار reference در
foreach و تأثیر آن روی آرایه اصلی دقت کنید و در نهایت، مقدار چاپشده را بنویسید.🔖 #PHP #پی_اچ_پی
👤 Developix
💎 Channel: @DevelopixPHP
👎2👍1
اصل Single Responsibility در کدهای PHP 🧱
یکی از مهمترین اصول SOLID که روی تمیزی کد PHP تاثیر مستقیم دارد، Single Responsibility Principle (SRP) است؛ یعنی هر کلاس فقط یک دلیل برای تغییر داشته باشد.
وقتی همهچیز را در یک کلاس میریزیم، بعد از مدتی هر تغییر کوچک تبدیل میشود به کابوس ریفکتور، با دهها باگ پنهان 😅
نمونه کد بد (نقض SRP) 👇
در این کلاس،
ریفکتور با SRP ✅
هر بخش را به مسئولیت خودش محدود میکنیم:
حالا:
• تغییر قوانین پسورد فقط روی
• تغییر دیتابیس یا ORM فقط در
• سوییچ از
چرا این ساختار در پروژه واقعی PHP (مثلاً Laravel) جواب میدهد؟
در فریمورکهایی مثل Laravel و Symfony همین ایده تکرار شده: Form Requestها برای validation، Repository / Model برای persistence، و Service / Mailer برای بیزنس لاجیک و ایمیل. SRP دقیقا پشت این تفکیک قرار دارد.
یک قدم ساده مثل جدا کردن validation و ایمیل از کلاس اصلی، کد را:
• قابل تستتر میکند (Unit Test روی هر کلاس جدا)
• قابل ریفکتورتر میکند
• خوانایی تیمی را بالا میبرد
موقع نوشتن کلاس بعدی، فقط از خودت بپرس:
این کلاس دقیقاً مسئول چه کاری است؟ اگر جواب بیشتر از یک جمله شد، یعنی وقت ریفکتور است 😉
منابع پیشنهادی برای مطالعه بیشتر:
PHP The Right Way - SOLID
Single Responsibility Principle (Wikipedia)
🔖 #PHP #پی_اچ_پی #PHP #Clean_Code #SOLID #SRP #Architecture
👤 Developix
💎 Channel: @DevelopixPHP
یکی از مهمترین اصول SOLID که روی تمیزی کد PHP تاثیر مستقیم دارد، Single Responsibility Principle (SRP) است؛ یعنی هر کلاس فقط یک دلیل برای تغییر داشته باشد.
وقتی همهچیز را در یک کلاس میریزیم، بعد از مدتی هر تغییر کوچک تبدیل میشود به کابوس ریفکتور، با دهها باگ پنهان 😅
نمونه کد بد (نقض SRP) 👇
<?php
class UserService
{
public function register(string $email, string $password): void
{
// 1) validation
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
throw new InvalidArgumentException('Invalid email');
}
if (strlen($password) < 8) {
throw new InvalidArgumentException('Weak password');
}
// 2) save to database
// imagine: DB queries here...
// 3) send welcome email
mail($email, 'Welcome', 'Thanks for registering');
}
}
در این کلاس،
UserService هم validation انجام میدهد، هم کار دیتابیس، هم ارسال ایمیل. سه دلیل برای تغییر در یک کلاس؛ این یعنی خلاف SRP.ریفکتور با SRP ✅
هر بخش را به مسئولیت خودش محدود میکنیم:
<?php
class UserValidator
{
public function validate(string $email, string $password): void
{
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
throw new InvalidArgumentException('Invalid email');
}
if (strlen($password) < 8) {
throw new InvalidArgumentException('Weak password');
}
}
}
class UserRepository
{
public function save(string $email, string $password): void
{
// persist user to DB (PDO / ORM / ...)
}
}
class Mailer
{
public function sendWelcome(string $email): void
{
// use real mailer here
}
}
class UserService
{
public function __construct(
private UserValidator $validator,
private UserRepository $repository,
private Mailer $mailer,
) {}
public function register(string $email, string $password): void
{
$this->validator->validate($email, $password);
$this->repository->save($email, $password);
$this->mailer->sendWelcome($email);
}
}
حالا:
• تغییر قوانین پسورد فقط روی
UserValidator اثر دارد 🔐• تغییر دیتابیس یا ORM فقط در
UserRepository انجام میشود 🗄️• سوییچ از
mail() به مثلاً Symfony Mailer فقط در Mailer عوض میشود 📧چرا این ساختار در پروژه واقعی PHP (مثلاً Laravel) جواب میدهد؟
در فریمورکهایی مثل Laravel و Symfony همین ایده تکرار شده: Form Requestها برای validation، Repository / Model برای persistence، و Service / Mailer برای بیزنس لاجیک و ایمیل. SRP دقیقا پشت این تفکیک قرار دارد.
یک قدم ساده مثل جدا کردن validation و ایمیل از کلاس اصلی، کد را:
• قابل تستتر میکند (Unit Test روی هر کلاس جدا)
• قابل ریفکتورتر میکند
• خوانایی تیمی را بالا میبرد
موقع نوشتن کلاس بعدی، فقط از خودت بپرس:
این کلاس دقیقاً مسئول چه کاری است؟ اگر جواب بیشتر از یک جمله شد، یعنی وقت ریفکتور است 😉
منابع پیشنهادی برای مطالعه بیشتر:
PHP The Right Way - SOLID
Single Responsibility Principle (Wikipedia)
🔖 #PHP #پی_اچ_پی #PHP #Clean_Code #SOLID #SRP #Architecture
👤 Developix
💎 Channel: @DevelopixPHP
👍3❤2
🇮🇷 مخزن داخلی WP Mirror
این مخزن برای افرادی که دسترسی به اینترنت بینالمللی ندارند ایجاد شده و به راحتی از طریق اینترنت داخلی قابل دسترسی است. در حال حاضر شامل ۴۰۰ پلاگین اورجینال و رایگان از مخزن رسمی وردپرس است که بدون هیچگونه دستکاری و تغییر در اختیار شما قرار گرفته. به زودی پلاگینهای بیشتری به این مجموعه اضافه خواهد شد.
برای دریافت آخرین آپدیتها به صورت رایگان، از لینک زیر استفاده کنید:
http://wpexperts.ir
مخزن به صورت هفتگی آپدیت میشود.
🔖 #PHP #پی_اچ_پی
👤 Mojtaba
💎 Channel: @DevelopixPHP
این مخزن برای افرادی که دسترسی به اینترنت بینالمللی ندارند ایجاد شده و به راحتی از طریق اینترنت داخلی قابل دسترسی است. در حال حاضر شامل ۴۰۰ پلاگین اورجینال و رایگان از مخزن رسمی وردپرس است که بدون هیچگونه دستکاری و تغییر در اختیار شما قرار گرفته. به زودی پلاگینهای بیشتری به این مجموعه اضافه خواهد شد.
برای دریافت آخرین آپدیتها به صورت رایگان، از لینک زیر استفاده کنید:
http://wpexperts.ir
مخزن به صورت هفتگی آپدیت میشود.
🔖 #PHP #پی_اچ_پی
👤 Mojtaba
💎 Channel: @DevelopixPHP
👎7❤1
اگه تا حالا خواستی یه لاگین سبک برای SPA، موبایل یا حتی فرم ساده خودت بسازی، یه API لاگین کوچیک با PHP خالص میتونه عالی باشه؛ مخصوصاً وقتی با سبک مدرن و OOP نوشته بشه 😊
ایده این پست بر اساس ترکیبی از مستند رسمی PHP و چند نمونهکار تمیز روی GitHub هست (مثل ریپوهای سبک login API با PDO). تمرکز روی اینه که یه ساختار تمیز، قابلگسترش و امنتر نسبت به کدهای قدیمی و procedural داشته باشیم.
سناریو 🔎
میخوای یه endpoint مثل
• JSON از کلاینت بگیره (email و password)
• یوزر رو توی دیتابیس MySQL چک کنه
• پسورد رو با
• در جواب، JSON تمیز برگردونه
چند نکته مهم قبل از کد 🧠
• حتماً
• همیشه
• خطاها رو JSON برگردون، نه echo ساده.
نمونه ساختار ساده API لاگین 🧩
این یه مثال مینیمال و قابلاجراست (فرض بر اینه که جدول users با ستونهای id، email، password داری و پسوردها با
چرا این سبک خوبه؟ ⚙️
• کلاس DB جداست، بعداً راحت میتونی لاگ، کش یا تست واحد براش بنویسی.
• LoginController فقط روی لاجیک لاگین تمرکز داره، نه اتصال به دیتابیس.
• از
برای عمیقتر شدن توی این سبک، مستند رسمی PHP درباره PDO و همچنین بخش password hash و password_verify خیلی کمککننده است.
این ساختار کوچیک رو بردار، توی پروژههات امتحانش کن و با اضافه کردن token (مثلاً JWT) یا session، تبدیلش کن به یه auth کاملتر. تجربههات رو هم با بقیه توسعهدهندههای PHP به اشتراک بذار 🔧💬
🔖 #PHP #پی_اچ_پی #PHP #Login_API #PDO #OOP #Authentication #Backend
👤 Developix
💎 Channel: @DevelopixPHP
ایده این پست بر اساس ترکیبی از مستند رسمی PHP و چند نمونهکار تمیز روی GitHub هست (مثل ریپوهای سبک login API با PDO). تمرکز روی اینه که یه ساختار تمیز، قابلگسترش و امنتر نسبت به کدهای قدیمی و procedural داشته باشیم.
سناریو 🔎
میخوای یه endpoint مثل
/api/login.php داشته باشی که:• JSON از کلاینت بگیره (email و password)
• یوزر رو توی دیتابیس MySQL چک کنه
• پسورد رو با
password_hash و password_verify هندل کنه• در جواب، JSON تمیز برگردونه
چند نکته مهم قبل از کد 🧠
• حتماً
PDO با prepared statement استفاده کن، نه query خام.• همیشه
Content-Type: application/json رو ست کن.• خطاها رو JSON برگردون، نه echo ساده.
نمونه ساختار ساده API لاگین 🧩
این یه مثال مینیمال و قابلاجراست (فرض بر اینه که جدول users با ستونهای id، email، password داری و پسوردها با
password_hash ذخیره شدن):<?php
// api/login.php
declare(strict_types=1);
header('Content-Type: application/json; charset=utf-8');
class DB
{
private \PDO $pdo;
public function __construct()
{
$dsn = 'mysql:host=localhost;dbname=myapp;charset=utf8mb4';
$user = 'db_user';
$pass = 'db_pass';
$this->pdo = new \PDO($dsn, $user, $pass, [
\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
\PDO::ATTR_DEFAULT_FETCH_MODE => \PDO::FETCH_ASSOC,
]);
}
public function findUserByEmail(string $email): ?array
{
$stmt = $this->pdo->prepare('SELECT * FROM users WHERE email = :email LIMIT 1');
$stmt->execute(['email' => $email]);
$user = $stmt->fetch();
return $user ?: null;
}
}
class LoginController
{
public function __construct(private DB $db) {}
public function handle(): void
{
$input = json_decode(file_get_contents('php://input'), true);
if (!isset($input['email'], $input['password'])) {
http_response_code(400);
echo json_encode(['error' => 'invalid_payload']);
return;
}
$user = $this->db->findUserByEmail($input['email']);
if (!$user || !password_verify($input['password'], $user['password'])) {
http_response_code(401);
echo json_encode(['error' => 'invalid_credentials']);
return;
}
echo json_encode([
'id' => (int) $user['id'],
'email' => $user['email'],
]);
}
}
$db = new DB();
$controller = new LoginController($db);
$controller->handle();
چرا این سبک خوبه؟ ⚙️
• کلاس DB جداست، بعداً راحت میتونی لاگ، کش یا تست واحد براش بنویسی.
• LoginController فقط روی لاجیک لاگین تمرکز داره، نه اتصال به دیتابیس.
• از
strict_types و type hint استفاده شده که با PHP مدرن هماهنگه.برای عمیقتر شدن توی این سبک، مستند رسمی PHP درباره PDO و همچنین بخش password hash و password_verify خیلی کمککننده است.
این ساختار کوچیک رو بردار، توی پروژههات امتحانش کن و با اضافه کردن token (مثلاً JWT) یا session، تبدیلش کن به یه auth کاملتر. تجربههات رو هم با بقیه توسعهدهندههای PHP به اشتراک بذار 🔧💬
🔖 #PHP #پی_اچ_پی #PHP #Login_API #PDO #OOP #Authentication #Backend
👤 Developix
💎 Channel: @DevelopixPHP
👍3❤1
در نمونهکد بالا در بخش کد اشتباه برای گرفتن پستها و کامنتها در یک حلقه روی هر پست، یک Query جداگانه به دیتابیس ارسال شده است (مشکل معروف به N+1 Queries). این کار در اسکیل بالا فشار زیادی به دیتابیس وارد میکند و زمان پاسخگویی را بهشدت بالا میبرد.
در کد صحیح با استفاده از
اگر در پروژهی PHP/Laravel خود با Modelهای مرتبط زیاد سروکار دارید، به جای دسترسی تنبلی (Lazy Loading) داخل حلقه، از Eager Loading استفاده کنید تا هم Queryهای غیرضروری حذف شوند و هم در Loadهای بالا دچار افت شدید سرعت و فشار روی دیتابیس نشوید.
🔖 #PHP #پی_اچ_پی
👤 Developix
💎 Channel: @DevelopixPHP
در کد صحیح با استفاده از
with('comments.user') همهی دادههای مورد نیاز بهصورت Eager Loading در چند Query محدود واکشی میشوند. به این ترتیب تعداد Queryها کاهش پیدا کرده، Latency پایین میآید و Performance در سناریوهایی مثل لیست کردن پستهای صفحهی اصلی یا Dashboard با تعداد زیاد رکورد بهمراتب بهتر میشود.اگر در پروژهی PHP/Laravel خود با Modelهای مرتبط زیاد سروکار دارید، به جای دسترسی تنبلی (Lazy Loading) داخل حلقه، از Eager Loading استفاده کنید تا هم Queryهای غیرضروری حذف شوند و هم در Loadهای بالا دچار افت شدید سرعت و فشار روی دیتابیس نشوید.
🔖 #PHP #پی_اچ_پی
👤 Developix
💎 Channel: @DevelopixPHP
در کد زیر، یک تابع برای trim کردن همه مقادیر یک آرایه چندبعدی نوشته شده است، اما نتیجهی نهایی بهدرستی کار نمیکند و آرایهی اصلی دچار رفتار عجیب میشود:
در این کد از reference در حلقههای
چه چیزی باید در این کد اصلاح شود تا هم Memory Leak و هم رفتار غیرمنتظره روی آرایهی اصلی برطرف شود؟
🔖 #PHP #پی_اچ_پی
👤 Developix
💎 Channel: @DevelopixPHP
<?php
$data = [
['name' => ' Ali ', 'email' => ' ali@example.com '],
['name' => ' Sara ', 'email' => ' sara@example.com'],
];
function deepTrim(array $items): array
{
foreach ($items as &$row) {
foreach ($row as &$value) {
$value = trim($value);
}
}
return $items;
}
$result = deepTrim($data);
print_r($data);
print_r($result);
در این کد از reference در حلقههای
foreach استفاده شده است و باعث بروز باگ پنهان در آرایهی اصلی میشود.چه چیزی باید در این کد اصلاح شود تا هم Memory Leak و هم رفتار غیرمنتظره روی آرایهی اصلی برطرف شود؟
🔖 #PHP #پی_اچ_پی
👤 Developix
💎 Channel: @DevelopixPHP
خروجی نهایی اجرای این کد در PHP چیست؟
توجه کنید که از closure بازگشتی و متغیر static داخل تابع استفاده شده است و ترتیب فراخوانی تابع اهمیت دارد.
خروجی دقیق این اسکریپت (دو خط echo شده) را بنویسید.
🔖 #PHP #پی_اچ_پی
👤 Developix
💎 Channel: @DevelopixPHP
توجه کنید که از closure بازگشتی و متغیر static داخل تابع استفاده شده است و ترتیب فراخوانی تابع اهمیت دارد.
<?php
function makeCounter() {
static $base = 1;
$multiplier = 2;
$f = function($n) use (&$f, $multiplier) {
static $inner = 0;
$inner += $n;
if ($n <= 1) {
return $inner * $multiplier;
}
return $f($n - 1) + $inner;
};
$result = $f($base + 2);
$base += 2;
return $result;
}
echo makeCounter() . "\n";
echo makeCounter() . "\n";
خروجی دقیق این اسکریپت (دو خط echo شده) را بنویسید.
🔖 #PHP #پی_اچ_پی
👤 Developix
💎 Channel: @DevelopixPHP
خروجی اجرای این کد در PHP چیست؟
به ترتیب سه خط خروجی این اسکریپت را بنویس.
🔖 #PHP #پی_اچ_پی
👤 Developix
💎 Channel: @DevelopixPHP
$val = "9";
for ($i = 0; $i < 3; $i++) {
$val++;
}
echo $val . "\n";
$val2 = "A9";
$val2++;
echo $val2 . "\n";
$val3 = "09";
$val3++;
echo $val3 . "\n";
به ترتیب سه خط خروجی این اسکریپت را بنویس.
🔖 #PHP #پی_اچ_پی
👤 Developix
💎 Channel: @DevelopixPHP
👍1
Forwarded from Developix Support
This media is not supported in your browser
VIEW IN TELEGRAM
🏆آفرهای جام جهانی ۲۰۲۶ هاستایران فعال شد!
با کمپین «ترکیب برنده سایتت»، زیرساخت سایتت رو برای روزهای پرترافیک آماده کن:
🔥 ۲۵٪ تخفیف روی پلنهای ۳ ماهه هاست اشتراکی ایران
⚡ ۵۰٪ تخفیف روی پلنهای یکماهه سرویس ابری در دیتاسنترهای تهران، مشهد و اهواز
🧠 مشاوره رایگان زیرساخت توسط کارشناسان هاستایران
فرصت استفاده از تخفیفها و ثبت فرم مشاوره محدود است.
📌 برای کپی کدهای تخفیف و ثبتنام در فرم مشاوره، روی لینک زیر کلیک کنید:
📌صفحه فرم مشاوره
📌تلگرام هاستایران
📌بله هاستایران
#هاست_ایران #سرور_ابری_هاست_ایران #هاست_اشتراکی #دیتاسنتر #مشاوره_زیرساخت #جام_جهانی2026
با کمپین «ترکیب برنده سایتت»، زیرساخت سایتت رو برای روزهای پرترافیک آماده کن:
🔥 ۲۵٪ تخفیف روی پلنهای ۳ ماهه هاست اشتراکی ایران
⚡ ۵۰٪ تخفیف روی پلنهای یکماهه سرویس ابری در دیتاسنترهای تهران، مشهد و اهواز
🧠 مشاوره رایگان زیرساخت توسط کارشناسان هاستایران
فرصت استفاده از تخفیفها و ثبت فرم مشاوره محدود است.
📌 برای کپی کدهای تخفیف و ثبتنام در فرم مشاوره، روی لینک زیر کلیک کنید:
📌صفحه فرم مشاوره
📌تلگرام هاستایران
📌بله هاستایران
#هاست_ایران #سرور_ابری_هاست_ایران #هاست_اشتراکی #دیتاسنتر #مشاوره_زیرساخت #جام_جهانی2026
👎1
اگه برای هر صفحهی پروژهی PHP خودت یه فایل جدا مثل
این پست بر اساس ایدهها و الگوی PSR-7 و نمونههای سادهای مثل klein.php یه روتر سبک رو نشون میده که به راحتی تو هر پروژه PHP 8 میتونی استفادهاش کنی.
ایدهی اصلی چیه؟
✅ همهی request ها از یه
✅ بر اساس
✅ کدهای صفحهها بهجای پخش شدن، در توابع/کلاسها باشن
ساخت یک Router خیلی ساده
تو public روت پروژه، یه
الان وقتی بری به
یه کم تمیزتر با کلاس
میتونی روتر رو تو یه کلاس بذاری (مثلا
چرا این کار مفیده؟
• اضافه کردن route جدید فقط با یه خط تو آرایه انجام میشه 🔧
• بعدا میتونی middleware، auth، یا JSON API رو راحت اضافه کنی
• قدم اولیه برای مهاجرت به معماری تمیزتر و نزدیکتر به استانداردهایی مثل PSR هست
امتحانش کن، یه پروژه کوچیک بساز و چند تا route تعریف کن. اگه برات مفید بود، برای بقیهی PHP dev ها هم بفرست تا اونها هم از این ساختار تمیزتر لذت ببرن 👨💻👩💻
🔖 #PHP #پی_اچ_پی #PHP #Routing #Web #Backend #Modern_PHP #PSR
👤 Developix
💎 Channel: @DevelopixPHP
about.php، contact.php و ... میسازی، کمکم همهچی شلوغ و سختقابلمدیریت میشه. یه Router ساده میتونه کل مسیرها رو تمیز و قابلگسترش کنه، حتی بدون استفاده از فریمورکی مثل Laravel 👌این پست بر اساس ایدهها و الگوی PSR-7 و نمونههای سادهای مثل klein.php یه روتر سبک رو نشون میده که به راحتی تو هر پروژه PHP 8 میتونی استفادهاش کنی.
ایدهی اصلی چیه؟
✅ همهی request ها از یه
index.php رد بشن (Front Controller)✅ بر اساس
REQUEST_METHOD و REQUEST_URI، تابع یا Controller مناسب صدا زده بشه✅ کدهای صفحهها بهجای پخش شدن، در توابع/کلاسها باشن
ساخت یک Router خیلی ساده
تو public روت پروژه، یه
index.php بساز و کد زیر رو بذار:<?php
declare(strict_types=1);
$routes = [
'GET' => [
'/' => function () {
echo 'Home Page';
},
'/about' => function () {
echo 'About Page';
},
],
'POST' => [
'/contact' => function () {
echo 'Form submitted';
},
],
];
$method = $_SERVER['REQUEST_METHOD'] ?? 'GET';
$uri = parse_url($_SERVER['REQUEST_URI'] ?? '/', PHP_URL_PATH);
if (isset($routes[$method][$uri])) {
$handler = $routes[$method][$uri];
$handler();
} else {
http_response_code(404);
echo '404 Not Found';
}
الان وقتی بری به
/ یا /about یا با POST بری به /contact، روترت دقیقا میدونه چی رو اجرا کنه 🙌یه کم تمیزتر با کلاس
میتونی روتر رو تو یه کلاس بذاری (مثلا
src/Router.php) و با composer و autoload استفادهاش کنی. نمونهی خیلی شبیه به این ساختار رو تو پروژههای کوچیک GitHub مثل "simple-php-router" راحت پیدا میکنی و میتونی ایده بگیری.چرا این کار مفیده؟
• اضافه کردن route جدید فقط با یه خط تو آرایه انجام میشه 🔧
• بعدا میتونی middleware، auth، یا JSON API رو راحت اضافه کنی
• قدم اولیه برای مهاجرت به معماری تمیزتر و نزدیکتر به استانداردهایی مثل PSR هست
امتحانش کن، یه پروژه کوچیک بساز و چند تا route تعریف کن. اگه برات مفید بود، برای بقیهی PHP dev ها هم بفرست تا اونها هم از این ساختار تمیزتر لذت ببرن 👨💻👩💻
🔖 #PHP #پی_اچ_پی #PHP #Routing #Web #Backend #Modern_PHP #PSR
👤 Developix
💎 Channel: @DevelopixPHP
👍5
Forwarded from | کانال ربات تلگرام |
🧩 ورژن 4 فریمورک LaraGram منتشر شد.
یکی از مهمترین قابلیتهای LaraGram 4، معرفی پکیج MTProto است؛ پکیجی که با هدف سادهسازی توسعه پروژههای مبتنی بر Telegram MTProto API طراحی شده است.
توسعه با MTProto معمولاً با چالشهایی مانند مدیریت Session، احراز هویت، نگهداری اتصال، دریافت Updateها، مدیریت Flood Wait و پیکربندیهای پیچیده همراه است. در LaraGram تلاش شده تمام این پیچیدگیها از مسیر توسعهدهنده حذف شود تا تجربهای مشابه توسعه یک ربات معمولی، اما با قدرت کامل MTProto داشته باشید.
⚡️ شروع کار بدون دردسر با LaraGram Installer
برای اینکه حتی مرحله راهاندازی هم ساده باشد، LaraGram Installer تمام مراحل اولیه را برای شما انجام میدهد.
با استفاده از Installer، فرآیندهایی مانند:
- نصب LaraGram
- نصب و آمادهسازی پکیج MTProto
- انجام کانفیگهای اولیه
- آمادهسازی ساختار پروژه
به صورت خودکار انجام میشود.
بعد از نصب، کافی است Handlerهای موردنظر خود را تعریف کنید و منطق برنامه را بنویسید؛ بخش زیادی از کارهای مربوط به زیرساخت، اتصال و مدیریت سرویس توسط خود LaraGram انجام خواهد شد.
⚡️ قدرت گرفته از Surge و Swoole/OpenSwoole
MTProto در LaraGram بر پایه Surge و Swoole/OpenSwoole توسعه داده شده است؛ یعنی به جای اجرای سنتی PHP، از یک Runtime دائمی و Event-Driven استفاده میکند.
این معماری باعث میشود MTProto بتواند برای ارتباطهای دائمی و پروژههای Real-Time عملکرد بسیار بهتری داشته باشد:
🚀 پردازش سریعتر Updateها
🔄 مدیریت همزمان اتصالها
💾 مصرف بهینهتر منابع
⚡️ حذف سربار اجرای مجدد برنامه
📈 آمادگی برای پروژههای بزرگ و پرترافیک
🧠 تمام امکانات MTProto، آماده استفاده
در MTProto LaraGram بسیاری از قابلیتهایی که معمولاً نیاز به پیادهسازی دستی دارند، به صورت داخلی فراهم شدهاند، به عنوان مثال شبیه سازی رفتار انسان، یا اعمال لیمیتهای خودکار به صورت هوشمند.
در نتیجه، توسعهدهنده به جای درگیر شدن با جزئیات سطح پایین، روی ساخت قابلیتهای اصلی پروژه تمرکز میکند.
🌐 MTProto + Web Routing؛ ساخت Telegram Client تحت وب
یکی از جذابترین بخشهای LaraGram 4، ترکیب MTProto با Web Framework جدید LaraGram است.
ترکیب این قابلیتها با MTProto به شما اجازه میدهد یک Telegram Web Client اختصاصی توسعه دهید؛ جایی که رابط کاربری از طریق سیستم وب LaraGram ساخته میشود و ارتباط مستقیم با تلگرام از طریق MTProto انجام میشود.
یعنی با یک اکوسیستم واحد میتوانید:
Backend وب را مدیریت کنید
با Telegram API ارتباط داشته باشید
حسابهای کاربری را مدیریت کنید
کلاینتها و سرویسهای اختصاصی تلگرامی بسازید
این تنها یکی از قابلیت های LaraGram است، پکیج Luna، یکی دیگر از آپدیتهای بزرگ LaraGram برای توسعه مینیاپ ها با React/Vue/Svelte بدون درگیری با API نویسی، SPAs، یا InitData تلگرام است.
همچنین پکیجهایی برای توسعه با AI، ماینتورینگ ربات و... در حال توسعه هستند.
نسخه 4 آغاز مسیر جدید LaraGram است؛ مسیری که این پروژه را از یک فریمورک ربات، به بستری کامل برای توسعه سرویسها، کلاینتها و اپلیکیشنهای مبتنی بر تلگرام تبدیل میکند.
📚 مستندات کامل: https://laraxgram.github.io
⭐️ اگر LaraGram برای شما مفید است، خوشحال میشویم با معرفی پروژه و دادن Star در GitHub از توسعه آن حمایت کنید:
🔹 گیتهاب LaraGram
🔹 گیتهاب MTProto
🔹 گیتهاب Luna
یکی از مهمترین قابلیتهای LaraGram 4، معرفی پکیج MTProto است؛ پکیجی که با هدف سادهسازی توسعه پروژههای مبتنی بر Telegram MTProto API طراحی شده است.
توسعه با MTProto معمولاً با چالشهایی مانند مدیریت Session، احراز هویت، نگهداری اتصال، دریافت Updateها، مدیریت Flood Wait و پیکربندیهای پیچیده همراه است. در LaraGram تلاش شده تمام این پیچیدگیها از مسیر توسعهدهنده حذف شود تا تجربهای مشابه توسعه یک ربات معمولی، اما با قدرت کامل MTProto داشته باشید.
⚡️ شروع کار بدون دردسر با LaraGram Installer
برای اینکه حتی مرحله راهاندازی هم ساده باشد، LaraGram Installer تمام مراحل اولیه را برای شما انجام میدهد.
با استفاده از Installer، فرآیندهایی مانند:
- نصب LaraGram
- نصب و آمادهسازی پکیج MTProto
- انجام کانفیگهای اولیه
- آمادهسازی ساختار پروژه
به صورت خودکار انجام میشود.
بعد از نصب، کافی است Handlerهای موردنظر خود را تعریف کنید و منطق برنامه را بنویسید؛ بخش زیادی از کارهای مربوط به زیرساخت، اتصال و مدیریت سرویس توسط خود LaraGram انجام خواهد شد.
⚡️ قدرت گرفته از Surge و Swoole/OpenSwoole
MTProto در LaraGram بر پایه Surge و Swoole/OpenSwoole توسعه داده شده است؛ یعنی به جای اجرای سنتی PHP، از یک Runtime دائمی و Event-Driven استفاده میکند.
این معماری باعث میشود MTProto بتواند برای ارتباطهای دائمی و پروژههای Real-Time عملکرد بسیار بهتری داشته باشد:
🚀 پردازش سریعتر Updateها
🔄 مدیریت همزمان اتصالها
💾 مصرف بهینهتر منابع
⚡️ حذف سربار اجرای مجدد برنامه
📈 آمادگی برای پروژههای بزرگ و پرترافیک
🧠 تمام امکانات MTProto، آماده استفاده
در MTProto LaraGram بسیاری از قابلیتهایی که معمولاً نیاز به پیادهسازی دستی دارند، به صورت داخلی فراهم شدهاند، به عنوان مثال شبیه سازی رفتار انسان، یا اعمال لیمیتهای خودکار به صورت هوشمند.
در نتیجه، توسعهدهنده به جای درگیر شدن با جزئیات سطح پایین، روی ساخت قابلیتهای اصلی پروژه تمرکز میکند.
نکته: به دلیل استفاده از Swoole/OpenSwoole، پکیج MTProto روی هاستهای اشتراکی قابل اجرا نیست و برای استفاده از آن به یک VPS نیاز خواهید داشت.
🌐 MTProto + Web Routing؛ ساخت Telegram Client تحت وب
یکی از جذابترین بخشهای LaraGram 4، ترکیب MTProto با Web Framework جدید LaraGram است.
ترکیب این قابلیتها با MTProto به شما اجازه میدهد یک Telegram Web Client اختصاصی توسعه دهید؛ جایی که رابط کاربری از طریق سیستم وب LaraGram ساخته میشود و ارتباط مستقیم با تلگرام از طریق MTProto انجام میشود.
یعنی با یک اکوسیستم واحد میتوانید:
Backend وب را مدیریت کنید
با Telegram API ارتباط داشته باشید
حسابهای کاربری را مدیریت کنید
کلاینتها و سرویسهای اختصاصی تلگرامی بسازید
این تنها یکی از قابلیت های LaraGram است، پکیج Luna، یکی دیگر از آپدیتهای بزرگ LaraGram برای توسعه مینیاپ ها با React/Vue/Svelte بدون درگیری با API نویسی، SPAs، یا InitData تلگرام است.
همچنین پکیجهایی برای توسعه با AI، ماینتورینگ ربات و... در حال توسعه هستند.
نسخه 4 آغاز مسیر جدید LaraGram است؛ مسیری که این پروژه را از یک فریمورک ربات، به بستری کامل برای توسعه سرویسها، کلاینتها و اپلیکیشنهای مبتنی بر تلگرام تبدیل میکند.
📚 مستندات کامل: https://laraxgram.github.io
⭐️ اگر LaraGram برای شما مفید است، خوشحال میشویم با معرفی پروژه و دادن Star در GitHub از توسعه آن حمایت کنید:
🔹 گیتهاب LaraGram
🔹 گیتهاب MTProto
🔹 گیتهاب Luna
❤2
Forwarded from Developix Support
با Migration Boost هاستایران، برای مهاجرت به سرور ابری دوباره هزینه ترافیک نده! 🚀
با خرید اولین سرور ابری غیرساعتی از **هاستایران**، بسته ترافیک هدیه مهاجرت بهصورت خودکار برای سرویس شما فعال میشود:
✅ حداقل ۱۰۰ گیگابایت ترافیک هدیه مهاجرت
✅ افزایش حجم هدیه متناسب با ظرفیت دیسک اولیه
✅ ترافیک آپلود رایگان
✅ بدون محدودیت زمانی
سرور ابری هاستایران را راهاندازی کنید و بکاپها، فایلها و پایگاه داده خود را بدون دغدغه هزینههای پنهان ترافیک منتقل کنید.
👇 مشاهده پلنهای سرور ابری هاستایران
hostiran.club/Migration
hostiran.club/Migration
با خرید اولین سرور ابری غیرساعتی از **هاستایران**، بسته ترافیک هدیه مهاجرت بهصورت خودکار برای سرویس شما فعال میشود:
✅ حداقل ۱۰۰ گیگابایت ترافیک هدیه مهاجرت
✅ افزایش حجم هدیه متناسب با ظرفیت دیسک اولیه
✅ ترافیک آپلود رایگان
✅ بدون محدودیت زمانی
سرور ابری هاستایران را راهاندازی کنید و بکاپها، فایلها و پایگاه داده خود را بدون دغدغه هزینههای پنهان ترافیک منتقل کنید.
👇 مشاهده پلنهای سرور ابری هاستایران
hostiran.club/Migration
hostiran.club/Migration
ساخت فرم لاگین امن با PHP با استفاده از password_hash 🔐
خیلی از پروژههای PHP هنوز از md5 یا sha1 برای ذخیره پسورد استفاده میکنن و این یعنی دردسر امنیتی 😅
بیایم یه لاگین ساده ولی استاندارد بسازیم که روی password_hash و password_verify سوار باشه؛ همون چیزی که توی داک رسمی PHP هم پیشنهاد شده:
php.net/manual/en/function.password-hash.php
ایده کلی اینه:
• سمت دیتابیس فقط hash پسورد ذخیره میشه، نه خود پسورد.
• برای ساخت یوزر جدید از password_hash استفاده میکنیم.
• برای لاگین از password_verify کمک میگیریم.
• بعد از لاگین موفق، یه session امن راه میندازیم.
این یه مثال خیلی مینیمال و قابلاستفاده توی پروژههای کوچیکه 👇
نکتهها و ترفندهای کوچیک ولی مهم:
• الگوریتم داخلی PASSWORD_DEFAULT ممکنه در آینده عوض بشه، ولی همون برای اکثر سناریوها عالیه.
• با password_needs_rehash میتونی موقع لاگین، hashهای قدیمی رو خودکار به نسخهی جدیدتر migrate کنی (مثلاً وقتی cost رو عوض کردی).
• حتماً روی ستون پسورد توی دیتابیس حداقل طول 255 بگذار تا با تغییر الگوریتمهای آینده مشکل نداشته باشی.
• از PDO prepared statement استفاده کن که جلوی SQL Injection رو بگیره، مثل همین نمونه.
• بعد لاگین، session_regenerate_id رو فراموش نکن تا Session Fixation اتفاق نیفته.
این الگو پایهی خیلی از سیستمهای auth امروزی توی PHP ـه و راحت میشه بعداً روش چیزهایی مثل remember me، محدودیت تلاش لاگین، و لاگ آدیت اضافه کرد.
امتحانش کن روی یه پروژه کوچیک، اگر جواب داد همون رو تمیزتر کن و بذار توی پروژههای اصلیات 💻
🔖 #PHP #پی_اچ_پی #PHP #Authentication #Security #Password_Hashing #Login #PDO
👤 Developix
💎 Channel: @DevelopixPHP
خیلی از پروژههای PHP هنوز از md5 یا sha1 برای ذخیره پسورد استفاده میکنن و این یعنی دردسر امنیتی 😅
بیایم یه لاگین ساده ولی استاندارد بسازیم که روی password_hash و password_verify سوار باشه؛ همون چیزی که توی داک رسمی PHP هم پیشنهاد شده:
php.net/manual/en/function.password-hash.php
ایده کلی اینه:
• سمت دیتابیس فقط hash پسورد ذخیره میشه، نه خود پسورد.
• برای ساخت یوزر جدید از password_hash استفاده میکنیم.
• برای لاگین از password_verify کمک میگیریم.
• بعد از لاگین موفق، یه session امن راه میندازیم.
این یه مثال خیلی مینیمال و قابلاستفاده توی پروژههای کوچیکه 👇
<?php
// config.php
$pdo = new PDO(
'mysql:host=localhost;dbname=test;charset=utf8mb4',
'db_user',
'db_pass',
[PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]
);
// register.php - ساخت یوزر جدید
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$email = $_POST['email'] ?? '';
$password = $_POST['password'] ?? '';
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
exit('ایمیل نامعتبر است');
}
if (strlen($password) < 8) {
exit('پسورد باید حداقل 8 کاراکتر باشد');
}
$hash = password_hash($password, PASSWORD_DEFAULT);
$stmt = $pdo->prepare('INSERT INTO users (email, password_hash) VALUES (:email, :hash)');
$stmt->execute([
':email' => $email,
':hash' => $hash,
]);
echo 'ثبتنام با موفقیت انجام شد ✅';
}
// login.php - لاگین یوزر
session_start();
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$email = $_POST['email'] ?? '';
$password = $_POST['password'] ?? '';
$stmt = $pdo->prepare('SELECT id, password_hash FROM users WHERE email = :email');
$stmt->execute([':email' => $email]);
$user = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$user || !password_verify($password, $user['password_hash'])) {
exit('ایمیل یا پسورد اشتباه است');
}
session_regenerate_id(true);
$_SESSION['user_id'] = $user['id'];
echo 'خوش اومدی! 🎉';
}
نکتهها و ترفندهای کوچیک ولی مهم:
• الگوریتم داخلی PASSWORD_DEFAULT ممکنه در آینده عوض بشه، ولی همون برای اکثر سناریوها عالیه.
• با password_needs_rehash میتونی موقع لاگین، hashهای قدیمی رو خودکار به نسخهی جدیدتر migrate کنی (مثلاً وقتی cost رو عوض کردی).
• حتماً روی ستون پسورد توی دیتابیس حداقل طول 255 بگذار تا با تغییر الگوریتمهای آینده مشکل نداشته باشی.
• از PDO prepared statement استفاده کن که جلوی SQL Injection رو بگیره، مثل همین نمونه.
• بعد لاگین، session_regenerate_id رو فراموش نکن تا Session Fixation اتفاق نیفته.
این الگو پایهی خیلی از سیستمهای auth امروزی توی PHP ـه و راحت میشه بعداً روش چیزهایی مثل remember me، محدودیت تلاش لاگین، و لاگ آدیت اضافه کرد.
امتحانش کن روی یه پروژه کوچیک، اگر جواب داد همون رو تمیزتر کن و بذار توی پروژههای اصلیات 💻
🔖 #PHP #پی_اچ_پی #PHP #Authentication #Security #Password_Hashing #Login #PDO
👤 Developix
💎 Channel: @DevelopixPHP
👍4👎2
✴️ جستوجوی تکراری روی آرایه بزرگ توی حلقه
توی قطعهکد اول هر بار داخل حلقه
توی نسخهٔ دوم، اول یه lookup table میسازیم و بعد توی حلقه فقط روی یه
اگر قراره داخل حلقه روی آرایه بزرگ سرچ کنی، قبلش ساختار دادهات رو برای lookup بهینه کن؛ معمولاً یه
🔖 #PHP #پی_اچ_پی
👤 Developix
💎 Channel: @DevelopixPHP
توی قطعهکد اول هر بار داخل حلقه
array_search صدا زده شده؛ یعنی اگه ۱۰هزار تا یوزر داشته باشی و لیست بلاکها هم بزرگ باشه، عملاً میزنی دیتای خودت رو با دست خودت دیداس میکنی 😅توی نسخهٔ دوم، اول یه lookup table میسازیم و بعد توی حلقه فقط روی یه
isset ساده چک میکنیم؛ هم خواناتر میشه هم از نظر Time Complexity از O(n×m) میآد پایین به O(n+m) و فشار روی CPU بهشدت کمتر میشه.اگر قراره داخل حلقه روی آرایه بزرگ سرچ کنی، قبلش ساختار دادهات رو برای lookup بهینه کن؛ معمولاً یه
array_flip یا یه array_fill_keys درستحسابی، نصف bottleneck رو جمع میکنه.🔖 #PHP #پی_اچ_پی
👤 Developix
💎 Channel: @DevelopixPHP
🔥4
یک قطعهکد زیر را در نظر بگیرید (زبان: PHP). تمرکز روی رفتار generator و ارجاعها است.
بهنظر شما خروجی اجرای این اسکریپت چیست؟
خروجی را دقیقاً همانطور که در ترمینال چاپ میشود (با ترتیب و جداکنندهها) حدس بزنید.
🔖 #PHP #پی_اچ_پی
👤 Developix
💎 Channel: @DevelopixPHP
بهنظر شما خروجی اجرای این اسکریپت چیست؟
خروجی را دقیقاً همانطور که در ترمینال چاپ میشود (با ترتیب و جداکنندهها) حدس بزنید.
🔖 #PHP #پی_اچ_پی
👤 Developix
💎 Channel: @DevelopixPHP
🔥 پکیج: استاندارد PSR-11 برای Container
استاندارد PSR-11 فقط یه interface مشترک برای Containerهاست؛ خودش DI Container نیست، ولی باعث میشود بین فریمورکها و کتابخانهها راحتتر سوییچ کنی ✅
هر کتابخانهای که از PSR-11 پیروی کند، فقط با یک type-hint ساده مثل
برای جزئیات بیشتر، خود استاندارد را اینجا ببین:
لینک PSR Container
📥 دانلود: 1,102,739,550
⭐️ 10,032 علاقهمند
🔖 #PHP #پی_اچ_پی #PHP #PSR_11 #Container
💎 @DevelopixPHP
استاندارد PSR-11 فقط یه interface مشترک برای Containerهاست؛ خودش DI Container نیست، ولی باعث میشود بین فریمورکها و کتابخانهها راحتتر سوییچ کنی ✅
هر کتابخانهای که از PSR-11 پیروی کند، فقط با یک type-hint ساده مثل
Psr\Container\ContainerInterface با هر Container سازگار میشود.برای جزئیات بیشتر، خود استاندارد را اینجا ببین:
لینک PSR Container
📥 دانلود: 1,102,739,550
⭐️ 10,032 علاقهمند
🔖 #PHP #پی_اچ_پی #PHP #PSR_11 #Container
💎 @DevelopixPHP
👍2
برنامه نویسی سوکت در PHP بخش اول
عبارت دیگر در ارتباط های غیر سوکت برای ارسال یک پالس از سمت سرور به سمت کلاینت نیاز داریم که ابتدا یک درخواست به سمت سرور بدهیم تا بعد پاسخ را دریافت کنیم ولی در ارتباط سوکت می توان مستقیم از سرور به کلاینت ( یا کلاینت ها ) درخواست ارسال کنیم.
تصویر زیر نمونه یک ارتباط مانا میان یک کلاینت و یک سرور ( دو node در سوکت ) روی یک پورت می باشد. این ارتباط با ارسال یک پالس از سمت سرور به کلاینت شروع می شود و در ادامه پس از گذشت زمان دو پالس از سمت کلاینت به سرور می آید.
https://gnutec.net/socket-programming-in-php-part-1/
🔖 #PHP #پی_اچ_پی
👤 ابوالفضل
💎 Channel: @DevelopixPHP
عبارت دیگر در ارتباط های غیر سوکت برای ارسال یک پالس از سمت سرور به سمت کلاینت نیاز داریم که ابتدا یک درخواست به سمت سرور بدهیم تا بعد پاسخ را دریافت کنیم ولی در ارتباط سوکت می توان مستقیم از سرور به کلاینت ( یا کلاینت ها ) درخواست ارسال کنیم.
تصویر زیر نمونه یک ارتباط مانا میان یک کلاینت و یک سرور ( دو node در سوکت ) روی یک پورت می باشد. این ارتباط با ارسال یک پالس از سمت سرور به کلاینت شروع می شود و در ادامه پس از گذشت زمان دو پالس از سمت کلاینت به سرور می آید.
https://gnutec.net/socket-programming-in-php-part-1/
🔖 #PHP #پی_اچ_پی
👤 ابوالفضل
💎 Channel: @DevelopixPHP
👍2
ارسال ایمیل تأیید ثبتنام، بازیابی رمز عبور یا نوتیفیکیشن سفارش، تقریباً توی هر پروژه PHP جدی لازم میشود. اینجا با هم یک ماژول ساده و تمیز با PHPMailer میسازیم که هم امن باشد، هم قابلگسترش. 😉
منبع اصلیای که ایدهها ازش گرفته شده، داکیومنت رسمی و مثالهای PHPMailer در گیتهاب است؛ حتماً ارزش یک نگاه عمیقتر را دارد. 🔍
۱️⃣ نصب PHPMailer با Composer
اول مطمئن شو روی سرور یا سیستم لوکال، Composer نصب است. بعد داخل رoot پروژه این دستور را بزن:
composer require phpmailer/phpmailer
حالا پوشه vendor ساخته میشود و میتوانی از Autoload استفاده کنی.
۲️⃣ ساخت یک کلاس EmailService تمیز
بهجای اینکه هرجا لازم شد مستقیم شیء PHPMailer بسازی، بهتر است یک کلاس سرویس داشته باشی تا کانفیگ SMTP فقط یکجا باشد و بعداً راحت عوض شود (مثلاً وقتی از Gmail رفتی روی Mailgun یا SMTP هاست).
یک فایل مثل EmailService.php بساز و ساختار را شبیه مثال زیر نگه دار 👇
<?php
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
require __DIR__ . '/vendor/autoload.php';
class EmailService
{
private PHPMailer $mailer;
public function __construct()
{
$this->mailer = new PHPMailer(true);
// تنظیمات پایه SMTP
$this->mailer->isSMTP();
$this->mailer->Host = 'smtp.gmail.com';
$this->mailer->SMTPAuth = true;
$this->mailer->Username = 'your-email@gmail.com';
$this->mailer->Password = 'app-password-here';
$this->mailer->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
$this->mailer->Port = 587;
$this->mailer->setFrom('no-reply@yourapp.test', 'Your App');
$this->mailer->isHTML(true);
$this->mailer->CharSet = 'UTF-8';
}
public function send(string $to, string $subject, string $htmlBody): bool
{
try {
$this->mailer->clearAllRecipients();
$this->mailer->addAddress($to);
$this->mailer->Subject = $subject;
$this->mailer->Body = $htmlBody;
return $this->mailer->send();
} catch (Exception $e) {
error_log('Mail error: ' . $e->getMessage());
return false;
}
}
}
🔐 نکته مهم: برای Gmail باید از App Password استفاده کنی (نه پسورد عادی اکانت). راهنماش توی صفحه رسمی گوگل موجود است و بدون این کار معمولاً اتصال SMTP بلاک میشود.
۳️⃣ استفاده در سناریوی واقعی
مثلاً بعد از ثبتنام، یک لینک فعالسازی بفرست:
$emailService = new EmailService();
$activationLink = 'https://yourapp.test/activate?token=' . urlencode($token);
$html = "سلام {$userName}!<br>برای فعالسازی حسابت روی لینک زیر کلیک کن:<br><a href='{$activationLink}'>فعالسازی حساب";
$emailService->send($userEmail, 'فعالسازی حساب کاربری', $html);
🧩 چند نکته تجربی کوتاه:
- لاگ ارور را حتماً جایی ذخیره کن تا اگر روی سرور ایمیل نرسید، راحتتر دیباگ شود.
- محتوا را هم HTML نگه دار، هم یک نسخه متن ساده برای سازگاری بهتر با بعضی کلاینتها (قابلیت AltBody در PHPMailer).
- اطلاعات SMTP و پسوردها را داخل فایل env. نگه دار، نه مستقیم داخل کلاس.
در هر پروژه جدید، داشتن یک EmailService آماده کلی زمان ذخیره میکند. اگر این ساختار را کمی برای خودت شخصیسازی کنی، عملاً یک ماژول ایمیل قابلاستفاده مجدد برای تمام پروژههای PHP خواهی داشت. 🚀
🔖 #PHP #پی_اچ_پی #PHP #PHPMailer #Email #SMTP #Backend #Security
👤 Developix
💎 Channel: @DevelopixPHP
منبع اصلیای که ایدهها ازش گرفته شده، داکیومنت رسمی و مثالهای PHPMailer در گیتهاب است؛ حتماً ارزش یک نگاه عمیقتر را دارد. 🔍
۱️⃣ نصب PHPMailer با Composer
اول مطمئن شو روی سرور یا سیستم لوکال، Composer نصب است. بعد داخل رoot پروژه این دستور را بزن:
composer require phpmailer/phpmailer
حالا پوشه vendor ساخته میشود و میتوانی از Autoload استفاده کنی.
۲️⃣ ساخت یک کلاس EmailService تمیز
بهجای اینکه هرجا لازم شد مستقیم شیء PHPMailer بسازی، بهتر است یک کلاس سرویس داشته باشی تا کانفیگ SMTP فقط یکجا باشد و بعداً راحت عوض شود (مثلاً وقتی از Gmail رفتی روی Mailgun یا SMTP هاست).
یک فایل مثل EmailService.php بساز و ساختار را شبیه مثال زیر نگه دار 👇
<?php
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
require __DIR__ . '/vendor/autoload.php';
class EmailService
{
private PHPMailer $mailer;
public function __construct()
{
$this->mailer = new PHPMailer(true);
// تنظیمات پایه SMTP
$this->mailer->isSMTP();
$this->mailer->Host = 'smtp.gmail.com';
$this->mailer->SMTPAuth = true;
$this->mailer->Username = 'your-email@gmail.com';
$this->mailer->Password = 'app-password-here';
$this->mailer->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
$this->mailer->Port = 587;
$this->mailer->setFrom('no-reply@yourapp.test', 'Your App');
$this->mailer->isHTML(true);
$this->mailer->CharSet = 'UTF-8';
}
public function send(string $to, string $subject, string $htmlBody): bool
{
try {
$this->mailer->clearAllRecipients();
$this->mailer->addAddress($to);
$this->mailer->Subject = $subject;
$this->mailer->Body = $htmlBody;
return $this->mailer->send();
} catch (Exception $e) {
error_log('Mail error: ' . $e->getMessage());
return false;
}
}
}
🔐 نکته مهم: برای Gmail باید از App Password استفاده کنی (نه پسورد عادی اکانت). راهنماش توی صفحه رسمی گوگل موجود است و بدون این کار معمولاً اتصال SMTP بلاک میشود.
۳️⃣ استفاده در سناریوی واقعی
مثلاً بعد از ثبتنام، یک لینک فعالسازی بفرست:
$emailService = new EmailService();
$activationLink = 'https://yourapp.test/activate?token=' . urlencode($token);
$html = "سلام {$userName}!<br>برای فعالسازی حسابت روی لینک زیر کلیک کن:<br><a href='{$activationLink}'>فعالسازی حساب";
$emailService->send($userEmail, 'فعالسازی حساب کاربری', $html);
🧩 چند نکته تجربی کوتاه:
- لاگ ارور را حتماً جایی ذخیره کن تا اگر روی سرور ایمیل نرسید، راحتتر دیباگ شود.
- محتوا را هم HTML نگه دار، هم یک نسخه متن ساده برای سازگاری بهتر با بعضی کلاینتها (قابلیت AltBody در PHPMailer).
- اطلاعات SMTP و پسوردها را داخل فایل env. نگه دار، نه مستقیم داخل کلاس.
در هر پروژه جدید، داشتن یک EmailService آماده کلی زمان ذخیره میکند. اگر این ساختار را کمی برای خودت شخصیسازی کنی، عملاً یک ماژول ایمیل قابلاستفاده مجدد برای تمام پروژههای PHP خواهی داشت. 🚀
🔖 #PHP #پی_اچ_پی #PHP #PHPMailer #Email #SMTP #Backend #Security
👤 Developix
💎 Channel: @DevelopixPHP