| کانال توسعه‌دهندگان PHP |
1.72K subscribers
17 photos
36 links
⭕️ کانال توسعه‌دهندگان پی‌اچ‌پی (PHP) دولوپیکس

💠 دولوپیکس | جامعه توسعه‌دهندگان ایرانی

💎 @Developix
🚀 Developix.ir

📌 پشتیبانی و تبلیغات:
@DevelopixSupport
Download Telegram
استریم‌ ها در PHP - قسمت دهم

- متدهای قابل پیاده‌سازی در استریم رپرها


در قسمت قبل با ساخت یک استریم رپر سفارشی آشنا شدیم.
در کلاس‌های استریم رپر متدهایی با نام خاص پیاده‌سازی می‌شوند و هرکدام در مواقع خاص (مثل بازکردن استریم یا خواندن و نوشتن روی استریم) اجرا می‌شوند.

در ادامه با این متدها آشنا می‌شویم.

1- متد stream_open
این متد برای باز کردن استریم استفاده می‌شود.

پارامتر path مسیر استریم مثل mywrapper://file.txt
پارامتر mode حالت باز کردن مثل "r", "w", "a" و غیره
پارامتر options گزینه‌های اضافی (مثل STREAM_USE_PATH)
پارامتر opened_path ارجاعی برای مسیر واقعی باز شده (اختیاری)

public function stream_open(string $path, string $mode, int $options, ?string &$opened_path): bool {
$this->position = 0;
$this->data = "";
return true;
}

// Called if:
$fp = fopen("mywrapper://file.txt", "r");

در این مثال اشاره‌گر برابر 0 قرار می گیرید، داده اولیه برابر "" قرار می گیرد و در نهایت اعلام می شود که با موفقیت انجام شده.

2- متد stream_read
برای خواندن از استریم استفاده می‌شود.

پارامتر count تعداد بایتی که قرار است خوانده شود.

public function stream_read(int $count): string|false {
$result = substr($this->data, $this->position, $count);
$this->position += strlen($result);
return $result;
}

// Called if:
$data = fread($fp, 100);

این متد بخشی از داده را از موقعیت فعلی می‌خواند و موقعیت را جلو می‌برد.

3- متد stream_write
برای نوشتن در استریم به کار می‌رود.

پارامترdata رشته داده‌ای که باید نوشته شود.

public function stream_write(string $data): int {
$left = substr($this->data, 0, $this->position);
$right = substr($this->data, $this->position + strlen($data));
$this->data = $left . $data . $right;
$this->position += strlen($data);
return strlen($data);
}

// Called if:
fwrite($fp, "Hello World");

داده در محل اشاره‌گر نوشته شده و موقعیت جابجا می‌شود و طول داده نوشته شده برمی‌گردد.

4- متد stream_eof
بررسی رسیدن به انتهای استریم.

public function stream_eof(): bool {
return $this->position >= strlen($this->data);
}

// Called if:
if (feof($fp)) {
echo "End of file";
}


5- متد stream_tell
موقعیت فعلی خواندن/نوشتن در استریم را برمی‌گرداند.

public function stream_tell(): int {
return $this->position;
}

// Called if:
$pos = ftell($fp);


6- متد stream_seek
برای جابجایی موقعیت خواندن/نوشتن.

پارامتر offset جابجایی
پارامتر whence مبنا (SEEK_SET, SEEK_CUR, SEEK_END)

public function stream_seek(int $offset, int $whence): bool {
$length = strlen($this->data);
switch ($whence) {
case SEEK_SET:
if ($offset >= 0 && $offset <= $length) {
$this->position = $offset;
return true;
}
return false;
case SEEK_CUR:
//
case SEEK_END:
//
default:
return false;
}
}

// Called if:
fseek($fp, 10, SEEK_SET);

جابجایی موقعیت اشاره‌گر بر اساس $offset و مبنای $whence (ابتدا، موقعیت فعلی، یا انتها).

7- متد stream_close
برای بستن استریم و آزادسازی منابع.

public function stream_close(): void {
// free up resources.
}

// Called if:
fclose($fp);


8- متد stream_flush
برای خالی کردن بافر داده‌ها به مقصد نهایی.

public function stream_flush(): bool {
// Save or send data
return true;
}

// Called if:
fflush($fp);


9- متد stream_stat
بازگرداندن اطلاعات استریم مانند اندازه و زمان تغییرات.

public function stream_stat(): array|false {
return [
'size' => strlen($this->data),
'mtime' => time(),
'mode' => 0100666,
];
}

// Called if:
$fstat = fstat($fp);


10- متد url_stat
دریافت اطلاعات مسیر بدون باز کردن استریم.

پارامتر path مسیر کامل فایل یا دایرکتوری مثل "mywrapper://file.txt"
پارامتر flags فلگ‌هایی که اطلاعات بیشتری درباره نوع stat می‌دهند. معمولاً 0 یا ترکیبی از STREAM_URL_STAT_LINK (برای گرفتن اطلاعات لینک نمادین) یا STREAM_URL_STAT_QUIET (بدون تولید خطا)

public function url_stat(string $path, int $flags): array|false {
return $this->stream_stat();
}

// Called if:
stat("mywrapper://file.txt");


در قسمت بعد با سایر متدها آشنا خواهیم شد.

🔖 #PHP, #پی_اچ_پی

👤 AmirHossein

💎 Channel: @DevelopixPHP
🔥2👎1
استریم‌ ها در PHP - قسمت یازدهم

- متدهای قابل پیاده‌سازی در استریم رپرها - قسمت دوم


11- متد mkdir
ساخت دایرکتوری جدید با مسیر و دسترسی داده شده.

پارامتر path مسیر دایرکتوری که باید ساخته شود، مثلا "mywrapper://newdir"
پارامتر mode دسترسی‌های دایرکتوری (مثلا 0755)
پارامتر options گزینه‌هایی مانند STREAM_MKDIR_RECURSIVE که به شما اجازه می‌دهد ساخت چند مرحله‌ای دایرکتوری را انجام دهید.

public function mkdir(string $path, int $mode, int $options): bool {
// Creating a virtual directory
return true;
}

// Called if:
mkdir("mywrapper://newdir", 0755);


12- متد rmdir
برای حذف یک دایرکتوری.

پارامتر path مسیر دایرکتوری مورد نظر برای حذف
پارامتر options گزینه‌هایی که می‌توانند کنترل بیشتری بر حذف داشته باشند (در عمل معمولا 0)

public function rmdir(string $path, int $options): bool {
// Deleting a virtual directory
return true;
}

// Called if:
rmdir("mywrapper://newdir");


13- متد rename
جابجایی یا تغییر نام فایل یا دایرکتوری.

پارامتر path_from مسیر مبدأ
پارامتر path_to مسیر مقصد

public function rename(string $path_from, string $path_to): bool {
// Rename or move a file or directory
return true;
}

// Called if:
rename("mywrapper://old.txt", "mywrapper://new.txt");


14- متد unlink
حذف فایل مشخص شده.

پارامتر path مسیر فایل برای حذف

public function unlink(string $path): bool {
// Deleting a virtual file
return true;
}

// Called if:
unlink("mywrapper://file.txt");


15- متد dir_opendir
بازکردن دایرکتوری برای شروع خواندن محتویات.

پارامتر path مسیر دایرکتوری
پارامتر options گزینه‌ها (معمولاً 0)

public function dir_opendir(string $path, int $options): bool {
$this->dirEntries = ['file1.txt', 'file2.txt'];
$this->dirPosition = 0;
return true;
}

// Called if:
$dir = opendir("mywrapper://somedir");


16- متد dir_readdir
خواندن نام فایل یا دایرکتوری بعدی از داخل دایرکتوری باز شده.

public function dir_readdir(): string|bool {
if (isset($this->dirEntries[$this->dirPosition])) {
return $this->dirEntries[$this->dirPosition++];
}
return false;
}

// Called if:
while (($file = readdir($dir)) !== false) {
echo $file . "\n";
}


17- متد dir_rewinddir
بازگرداندن اشاره‌گر خواندن به ابتدای دایرکتوری.

public function dir_rewinddir(): bool {
$this->dirPosition = 0;
return true;
}

// Called if:
rewinddir($dir);


18- متد dir_closedir
بستن دایرکتوری و آزادسازی منابع.

public function dir_closedir(): bool {
// Resource liberation
return true;
}

// Called if:
closedir($dir);


19- متد stream_lock
اعمال قفل روی فایل برای هماهنگی دسترسی همزمان.

پارامتر operation نوع قفل مانند LOCK_SH (اشتراکی)، LOCK_EX (انحصاری)، یا LOCK_UN (آزادسازی قفل)

public function stream_lock(int $operation): bool {
// File lock management
return true;
}

// Called if:
flock($fp, LOCK_EX);


20- متد stream_metadata
مدیریت متادیتا مثل chmod و touch.

پارامتر path مسیر فایل یا دایرکتوری
پارامتر option نوع تغییر (مثلاً STREAM_META_ACCESS برای تغییر دسترسی، STREAM_META_TOUCH برای تغییر زمان)
پارامتر value مقدار جدید (مثلاً دسترسی جدید یا زمان)


public function stream_metadata(string $path, int $option, mixed $value): bool {
// Changing file and directory permissions or time
return true;
}

// Called if:
chmod("mywrapper://file.txt", 0644);
touch("mywrapper://file.txt", time());


21- متد stream_truncate
تغییر اندازه داده استریم (کوتاه کردن یا طولانی کردن).

پارامتر new_size اندازه جدید فایل

public function stream_truncate(int $new_size): bool {
$this->data = substr($this->data, 0, $new_size);
if (strlen($this->data) < $new_size) {
$this->data .= str_repeat("\0", $new_size - strlen($this->data));
}
return true;
}

// Called if:
ftruncate($fp, 1024);


22- متد stream_cast
تبدیل به resource (مثلاً برای socket).

پارامتر cast_as نوع resource مورد نظر

public function stream_cast(int $cast_as): resource|false {
return false;
}

// Called if:
if (stream_select($read, $write, $except, 0, 200000)) {
echo fread($read[0], 1024);
}


متدهای construct و destruct را نیز می‌توانید بسته به نیاز خود پیاده‌سازی کنید.

🔖 #PHP, #پی_اچ_پی

👤 AmirHossein

💎 Channel: @DevelopixPHP
👍4👎1
استریم‌ ها در PHP - قسمت دوازدهم

- ساخت فیلترهای سفارشی


در بخش سوم با استریم php://filter آشنا شدیم. همان‌طور که می‌دانید، این استریم امکان فیلتر کردن و پردازش داده‌های ورودی یا خروجی را در حین خواندن و نوشتن فراهم می‌کند. همچنین با فیلترهایی مانند string.toupper و string.strip_tags آشنا شدیم.

در PHP، کلاس php_user_filter پایه‌ای است برای تعریف فیلترهای استریم سفارشی (Custom Stream Filters). وقتی شما یک فیلتر سفارشی می‌سازید، باید از این کلاس ارث‌بری کنید و متدهای آن را پیاده‌سازی کنید تا بتوانید روی داده‌های استریم، پردازش دلخواه خود را انجام دهید.

- ساختار کلی کلاس php_user_filter

1- متد filter
این متد مهم‌ترین بخش فیلتر است. داده‌های ورودی از استریم در قالب یک یا چند "باکت" (bucket) به این متد می‌آیند. هدف شما این است که داده‌ها را در هر باکت پردازش کنید و سپس آن را به باکت‌های خروجی منتقل کنید.
public function filter(resource $in, resource $out, int &$consumed, bool $closing): int
{
//
}

پارامتر in : استریم ورودی که داده‌های خام در قالب باکت‌ها داخلش هستند.
پارامتر out : استریم خروجی که باید داده‌های پردازش شده داخلش قرار بگیرد.
پارامتر consumed : تعداد بایت‌هایی که از ورودی خوانده و مصرف شده‌اند. باید این مقدار را به‌روز کنید.
پارامتر closing : اگر true باشد، استریم در حال بسته شدن است و باید پردازش نهایی انجام شود.

این متد باید یک عدد صحیح را return کند، این عدد بین 0 تا 2 می باشد که در قالب ثابت های زیر موجود هستند:
ثابت PSFS_PASS_ON : ادامه معمولی پردازش (عدد 0)
ثابت PSFS_FEED_ME : منتظر داده بیشتر باش (عدد 1)
ثابت PSFS_ERR_FATAL : خطای بحرانی (عدد 2)

در ادامه یک فیلتر برای بزرگ کردن حروف ایجاد می کنیم:
public function filter(resource $in, resource $out, int &$consumed, bool $closing): int
{
while ($bucket = stream_bucket_make_writeable($in)) {
$bucket->data = strtoupper($bucket->data);

$consumed += $bucket->datalen;

stream_bucket_append($out, $bucket);
}

return PSFS_PASS_ON;
}

در هر تکرار، تابع stream_bucket_make_writeable($in) یک "باکت" داده‌ای از ورودی دریافت می‌کند.
باکت یک ساختار است که شامل داده‌های خام ($bucket->data) و طول داده‌ها ($bucket->datalen) است.
اگر داده‌ای وجود داشته باشد، باکت به صورت نوشتنی بازگردانده می‌شود.

در این مثال، داده‌های موجود در باکت به حروف بزرگ تبدیل می‌شوند:
$bucket->data = strtoupper($bucket->data);

یعنی هر رشته‌ای که از ورودی آمده، با strtoupper تبدیل به حروف بزرگ می‌شود.

تعداد بایت‌هایی که از ورودی خوانده شده است باید به $consumed اضافه شود:
$consumed += $bucket->datalen;

این به PHP کمک می‌کند بفهمد چقدر از داده‌ها مصرف شده‌اند.

پس از پردازش، باکت به استریم خروجی ارسال می‌شود:
stream_bucket_append($out, $bucket);

به این ترتیب، داده‌های پردازش شده آماده خواندن در خروجی هستند.

در نهایت، مقدار PSFS_PASS_ON برگردانده می‌شود، این مقدار به معنی "ادامه پردازش عادی" است و نشان می‌دهد که فیلتر با موفقیت کار خود را انجام داده است.

———

2- متد onCreate
این متد هنگام ایجاد فیلتر و اتصال آن به استریم فراخوانی می‌شود.
public function onCreate(): bool
{
//
}

می‌توانید در اینجا پارامترهای ورودی در $this->params را پردازش یا مقداردهی اولیه انجام دهید.
اگر مقدار true بازگردد، اجازه ساخت استریم داده می شود. در غیر این صورت ایجاد فیلتر به شکست می‌خورد.

———

3- متد onClose
زمانی که استریم بسته می‌شود، این متد فراخوانی می‌شود تا فیلتر بتواند منابع را آزاد کند یا تمیزکاری کند.
public function onClose(): void
{
//
}


نکته: تنها پیاده سازی متد filter اجباری می باشد.

- مثال کامل
class UppercaseFilter extends php_user_filter
{
public function filter($in, $out, &$consumed, $closing): int
{
while ($bucket = stream_bucket_make_writeable($in)) {
$bucket->data = strtoupper($bucket->data);
$consumed += $bucket->datalen;
stream_bucket_append($out, $bucket);
}
return PSFS_PASS_ON;
}
}

stream_filter_register('my_uppercase', 'UppercaseFilter') or die('Failed to register filter');

$fp = fopen('php://memory', 'r+');
fwrite($fp, "hello");
rewind($fp);
stream_filter_append($fp, 'my_uppercase');
echo stream_get_contents($fp); // HELLO

// OR

echo file_get_contents("php://filter/read=my_uppercase/resource=input.txt");


🔖 #PHP, #پی_اچ_پی

👤 AmirHossein

💎 Channel: @DevelopixPHP
🔥31👎1
خروجی کد بالا کدام است؟

A
Outer 1
Inner 1
Outer 2
Inner 1

B
Outer 1
Inner 1
Inner 2
Outer 2
Inner 1

C
Outer 1
Inner 1

D
Outer 1
Inner 1
Inner 2

💢 نکته : لطفا اندکی تامل کنید، از اجرای کد و استفاده از هوش مصنوعی خودداری کنید.

⚜️ پاسخ خود را همراه با توضیح ارسال کنید.

🔖 #PHP, #پی_اچ_پی

👤 AmirHossein

💎 Channel: @DevelopixPHP
2👍2
| کانال توسعه‌دهندگان PHP |
خروجی کد بالا کدام است؟ A Outer 1 Inner 1 Outer 2 Inner 1 B Outer 1 Inner 1 Inner 2 Outer 2 Inner 1 C Outer 1 Inner 1 D Outer 1 Inner 1 Inner 2 💢 نکته : لطفا اندکی تامل کنید، از اجرای کد و استفاده از هوش مصنوعی…
🔰 این سوال بسیار راحت است، درصورتی که با break و continue که با یک عدد همراه است آشنا باشید.

🔸 کد ما به این صورت است:
for ($i = 1; $i < 3; $i++) {
echo "Outer $i\n";
for ($j = 1; $j < 3; $j++) {
echo "\tInner $j\n";
if ($j == 1) break 2;
if ($j == 2) continue 2;
}
}

🔹 و خروجی آن گزینه C، یعنی:
Outer 1
Inner 1


⁉️ اما چرا؟
⚜️ بیایید ابتدا با دستورات break، و continue به صورت دقیق تر آشنا شویم.

🔻 ‏break N چیست؟
‏break به صورت معمول از یک حلقه خارج می‌شود. اما اگر بنویسیم break 2، به معنی خروج از دو سطح حلقه است.
یعنی در این کد:
if ($j == 1) break 2;

اگر شرط ‎$j == 1 برقرار شود، هم از حلقه داخلی و هم خارجی خارج می‌شود. یعنی اجرای کل حلقه‌ها متوقف می‌شود.

🔻continue N چیست؟
‏continue معمولاً ادامه حلقه جاری را رها می‌کند و می‌رود سراغ تکرار بعدی همان حلقه. اما continue 2 می‌گوید برو سراغ تکرار بعدی حلقه سطح دوم.
در این کد:
if ($j == 2) continue 2;

اگر این شرط اجرا شود، کل حلقه داخلی متوقف می‌شود و حلقه بیرونی به تکرار بعدی می‌رود.

🔸 در هر دو حالت، عدد بعد از break یا continue مشخص می‌کند که چند سطح از حلقه را تحت تأثیر قرار می‌دهد.
⭕️ نکته: عدد بعد از break یا continue باید به تعداد سطوح حلقه باشد.

⚜️ حالا بیایید ببینیم این کد دقیقاً چطور اجرا می‌شود:

اولین دور حلقه بیرونی: ‎$i = 1
Outer 1
اولین دور حلقه داخلی: ‎$j = 1
Inner 1
سپس:
if ($j == 1) break 2;


شرط درست است، پس اجرای break 2 انجام می‌شود. یعنی از هر دو حلقه خارج می‌شویم و برنامه پایان می‌یابد.

⭕️ نکته: دستور continue هرگز اجرا نخواهد شد.

🔖 #PHP, #پی_اچ_پی

👤 AmirHossein

💎 Channel: @DevelopixPHP
5👍1
‏LaraGram یک فریم‌ورک توسعه‌پذیر، منعطف و مدرن به زبان PHP برای ساخت ربات‌های تلگرامه که با الهام از ساختار لاراول طراحی شده.

اگر با لاراول آشنایی دارید، کار با LaraGram براتون راحت، لذت‌بخش و قابل پیش‌بینی خواهد بود — و حتی اگه آشنایی ندارید، ساختار منظمش خیلی زود براتون جا می‌افته.

‏LaraGram امکانات زیادی درون خودش داره که می‌تونید سخت‌ترین ربات‌ها رو با چند خط کد پیاده‌سازی کنید، اگر قابلیتی رو هم نداشته باشه می‌تونید به عنوان پکیج جانبی بهش اضافه کنید یا حتی برای اون پکیج توسعه بدید.

به عنوان مثال، LaraGram مجهز به یک سیستم Update Listener پیشرفته هست که به شما امکاناتی مانند گروه‌بندی لیسنرها، نام‌دهی به هر لیسنر، اعمال محدودیت و Middleware بر روی لیسنر، پردازش متن و ورودی‌ها، و... رو میده.

همچنین نسخه بازنویسی شده Eloquent ORM رو در خودش جا داده با پشتیبانی از ۵ دیتابیس مختلف، همراه با تعریف روابط، Migrations، Seeders و Factory‌ها.

سایر قابلیت های کلیدی اون:

🔐‌ سیستم کنترل مجوز با قابلیت تعریف Gate و Policy برای مدیریت دقیق سطح دسترسی کاربران به منابع مختلف.

💻‌ Commander System برای ساخت و اجرای راحت command‌ها، مدیریت ساده‌تر پروژه، و زمان‌بندی اجرای وظایف (Scheduled Tasks).

📨‌ ‏Queue و Job System برای ساخت صف و اجرای کارها در پس‌زمینه با زمان‌بندی دلخواه.

🧰‌ رابط Redis با امکانات لازم برای توسعه‌های وابسته به کش، صف و پیام‌رسانی آنی.

🧠‌ سیستم کشینگ با پشتیبانی از ۷ درایور مختلف برای ذخیره‌سازی داده‌های موقتی، به‌همراه پیاده‌سازی Step Manager بر همین بستر.

🔁‌ کالکشن‌ها برای کار ساده‌تر و منعطف‌تر با داده‌های Iterable، مشابه کالکشن‌های Laravel.

⚙️‏‌ Concurrency‏ داخلی با امکان پردازش هم‌زمان چند درخواست در پس‌زمینه بدون پیچیدگی اضافه.

🔒‌ ابزارهای امنیتی با پشتیبانی از سیستم‌های رمزنگاری (Crypt) و هشینگ (Hash).

📢‌ Event Dispatcher برای تعریف و مدیریت رویدادها و واکنش به آن‌ها.

🎛‌ کیبورد بیلدر توسعه‌یافته با استفاده ساده و انعطاف پذیری بالا.

🧩‌ موتور قالب‌سازی پیشرفته الهام‌گرفته از Blade برای ساخت پیام‌ها به‌صورت پویا و قابل نگهداری.

🌍‌ سیستم چندزبانه (Translation) برای ساخت ربات‌هایی با پشتیبانی از زبان‌های مختلف.

‌ سیستم اعتبارسنجی با قوانین متنوع و امکان تعریف Rule‌های سفارشی.

🤖‌ پشتیبانی از چند ربات هم‌زمان و امکان تعریف چند کانکشن و مدیریت آن‌ها به‌صورت مستقل.

یک مثال ساده برای ایجاد یک کامند بن با user_id به مدت 7 روز، با کنترل دسترسی و شرط ریپلای نشدن کامند:
Bot::onCommand("ban {id}", function (Request $request, $id) {
$request->banChatMember(
chat_id: chat()->id,
user_id: $id,
until_date: now()->addDays(7)->timestamp
);
})->can('administrator')->hasNotReply();


برخی از ویژگی‌ها با افزونه‌ها و پکیج‌های جانبی به LaraGram اضافه می‌شوند، به عنوان مثال:

⚡️LaraGram Surge
پکیجی برای اجرای سریع‌تر ربات‌ها با پشتیبانی از Swoole و OpenSwoole

🔧LaraGram Installer
برای نصب و راه‌اندازی سریع و ساده پروژه‌های LaraGram

🛢‌ LaraGram MongoDB‌‏
درایور پایگاه‌داده MongoDB برای Eloquent ORM


📚 مستندات رسمی LaraGram نیز از طریق لینک زیر در دسترس است:
🔗 laraxgram.github.io

💬 گروه پرسش و پاسخ:
🔹 @LaraGramChat

📌 پروژه در گیت‌هاب:
♦️ LaraGram

🔖 #TelegramBot, #ربات, #تلگرام

👤 AmirHossein

💎 Channel: @DevelopixRobot
👍6🔥31
Forwarded from | Erfan's Notes |
حدودا یک ماه از ریلیز شدن نسخه 3.0 وب‌اسمبلی (WASM) می‌گذره و الان فرصت کردم درموردش بخونم، تغییرات مهمی که داشته رو پایین می‌نویسم.

💠 پشتیبانی از Address Space های 64 بیت
تا قبل از این نسخه، وب‌اسمبلی محدود به آدرس‌های i32 بود و نمی‌تونست بیشتر از 4GB رو آدرس‌دهی کنه، ولی پشتیبانی از i64 اضافه شده و این محدودیت عملا بی‌نهایت شده، هرچند که همچنان مرورگرها حداکثر اجازه allocate کردن 16GB رو می‌دن.

💠 پشتیبانی از Memory های چندگانه
تا قبل از این نسخه، هر ماژول وب‌اسمبلی فقط محدود به یک Memory بود و برای تفکیک باید ماژول‌ها Split می‌شدند، ولی در این نسخه قابلیت داشتن Memory های متعدد برای یک ماژول اضافه شده.

💠 پشتیبانی از Garbage Collection
در این نسخه یک افزونه با عنوان wasm-gc اضافه شده که در سطوح پایین می‌تونه مموری رو به‌صورت خودکار مدیریت کنه، کامپایلرها می‌تونند Struct ها و آرایه‌ها و بعضی Integer ها رو به صورت تگ شده تعریف کنند و خود wasm وظیفه allocation و lifetime شون رو برعهده بگیره.

💠 پشتیبانی از Tail Call ها
قابلیت Tail Call به وب‌اسمبلی اضافه شده، این ویژگی از زبان‌های فانکشنال الگو گرفته، به این معنی که فانکشن‌ها می‌تونند در آخرین اکشن‌شون یک فانکشن دیگه‌ای رو کال کنند بدون اینکه فضایی از Stack رو اشغال کنند، این موضوع در کال های Recursive اهمیت زیادی داره.

💠 پشتیبانی از Exception ها
پشتیبانی از Exception های try و catch در وب‌اسمبلی اضافه شده، تا قبل از این برای چنین کاری باید از JS استفاده می‌شد.

💠 پشتیبانی از String های جاوا اسکریپت
قابلیت رد و بدل کردن مستقیم String های جاوا اسکریپت بدون نیاز به تبدیل دو طرفه اضافه شده، می‌تونید مقادر String رو به صورت مستقیم به‌عنوان externref پاس بدید و سمت wasm تغییرات لازم رو روش اعمال کنید و سمت JS تحویل بگیرید.

و البته کلی قابلیت دیگه که اگر دوست داشتید می‌تونید اینجا بخونید.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1🔥1
آشنایی با Reflection در PHP
بخش اول - مقدمه‌ای بر مفهوم Reflection

در بسیاری از مواقع، ممکن است بخواهیم برنامه‌ای بنویسیم که بتواند ساختار خود را در زمان اجرا بررسی و تحلیل کند.

به عنوان مثال:
- فریم‌ورکی که بتواند کنترلرها و متدهای آن‌ها را به صورت خودکار شناسایی کند؛
- ابزاری برای تست خودکار که بدون دخالت انسان، متدهای آزمون را پیدا و اجرا نماید؛
- یا حتی سیستمی که بر اساس type hintها، وابستگی‌ها را به صورت خودکار تزریق کند.

چنین قابلیت‌هایی با استفاده از Reflection API در PHP امکان‌پذیر است.
این ابزار یکی از بخش‌های پیشرفته و کمتر شناخته‌شده‌ی زبان PHP است که قدرت زیادی برای تحلیل، بازرسی و حتی تغییر رفتار کد در زمان اجرا در اختیار توسعه‌دهنده قرار می‌دهد.

تعریف Reflection

به طور خلاصه، Reflection در PHP به مجموعه‌ای از کلاس‌ها و متدها گفته می‌شود که امکان بازتاب (reflection) و خودشناسی (introspection) کد را در زمان اجرا فراهم می‌کنند.

به بیان دیگر، با استفاده از Reflection می‌توان:
- ساختار کلاس‌ها، توابع و متدها را شناسایی کرد،
- نوع و ویژگی‌های پارامترها را تشخیص داد،
- متدها را به صورت پویا فراخوانی کرد،
- و حتی به اعضای private و protected دسترسی پیدا نمود (در صورت نیاز و آگاهی از خطرات امنیتی آن).

کاربردهای Reflection در دنیای واقعی

‏Reflection در پروژه‌های واقعی کاربردهای متعددی دارد. در ادامه به برخی از مهم‌ترین آن‌ها اشاره می‌شود:

1- فریم‌ورک‌ها و سیستم‌های خودکارسازی
در فریم‌ورک‌هایی مانند Laravel و Symfony، از Reflection برای شناسایی خودکار کنترلرها، متدها و type hintها استفاده می‌شود.
به عنوان نمونه، در زمان اجرای Dependency Injection Container، با استفاده از Reflection مشخص می‌شود که هر کلاس چه نوع وابستگی‌هایی دارد و باید چه اشیایی به آن تزریق شود.

2- تست‌نویسی (Unit Testing)
در ابزارهایی مانند PHPUnit، از Reflection برای یافتن متدهایی استفاده می‌شود که با test آغاز می‌شوند.
همچنین از این قابلیت برای دسترسی به متدها و پراپرتی‌های خصوصی (private/protected) جهت تست دقیق‌تر منطق داخلی کلاس‌ها بهره گرفته می‌شود.

3- ‏ORM و Map کردن داده‌ها
کتابخانه‌هایی مانند Doctrine ORM از Reflection برای بررسی ساختار کلاس‌ها و تبدیل آن‌ها به جداول پایگاه داده استفاده می‌کنند.
در واقع، Reflection به ORM کمک می‌کند تا بدون نیاز به پیکربندی دستی، تشخیص دهد هر property به کدام ستون از جدول مرتبط است.

4- ابزارهای تحلیل و اشکال‌زدایی
ابزارهای Debug و Code Analysis می‌توانند با استفاده از Reflection، در زمان اجرا اطلاعات دقیقی از وضعیت کلاس‌ها و اشیاء جمع‌آوری کنند.
این اطلاعات در ساخت ابزارهای Documentation Generator، Profiler و Static Analyzer کاربرد فراوان دارد.

ملاحظات عملکرد و امنیت

هرچند Reflection امکانات بسیار قدرتمندی در اختیار توسعه‌دهنده قرار می‌دهد، اما باید در استفاده از آن احتیاط نمود:
- اجرای Reflection ممکن است اندکی باعث افزایش بار پردازشی (Performance Overhead) شود.
- دسترسی به متدها و پراپرتی‌های private/protected در صورت استفاده‌ی نادرست می‌تواند ریسک امنیتی ایجاد کند.

در نتیجه، پیشنهاد می‌شود Reflection تنها در مواردی مورد استفاده قرار گیرد که واقعاً به تحلیل یا رفتار پویا نیاز داریم، نه برای انجام کارهای ساده‌ای که می‌توان با روش‌های معمول انجام داد.

در بخش بعدی، به صورت گام‌به‌گام با کلاس‌های مختلف Reflection در PHP آشنا خواهیم شد و یاد می‌گیریم چگونه از آن‌ها برای ساخت ابزارها و سیستم‌های پویا استفاده کنیم.

🔖 #PHP, #پی_اچ_پی, #reflection

👤 AmirHossein

💎 Channel: @DevelopixPHP
👍2🔥1
امنیت ورودی‌ها همیشه نقطه‌ضعف اپلیکیشن‌هاست. استفاده از prepared statements در PDO یک راهکار ساده و مؤثر برای جلوگیری از SQL Injection است.

ایدهٔ اصلی (مختصر)
با آماده‌سازی کوئری و جدا کردن داده‌ها از ساختار SQL، هر ورودی به‌عنوان داده تفسیر می‌شود نه دستور SQL. در نتیجه حتی ورودی‌های مخرب اجرا نخواهند شد.

مثال شفاف
در این مثال یک اتصال PDO امن و نمونهٔ استفاده از پارامترهای نام‌دار را می‌بینید. دقت کنید که PDO::ERRMODE_EXCEPTION روشن است تا خطاها واضح باشند.

<?php
$pdo = new PDO('mysql:host=localhost;dbname=test;charset=utf8mb4', 'user', 'pass');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

// INSERT امن با پارامتر نام‌دار
$stmt = $pdo->prepare('INSERT INTO users (email, name) VALUES (:email, :name)');
$stmt->execute([':email' => $email, ':name' => $name]);

// استفادهٔ مجدد برای SELECT
$select = $pdo->prepare('SELECT * FROM users WHERE email = :email');
$select->execute([':email' => $email]);
$user = $select->fetch(PDO::FETCH_ASSOC);
?>


نکات عملی و خطاهای رایج
- هرگز ورودی‌ها را با string concatenation داخل کوئری قرار ندهید.
- از bindValue یا آرایهٔ execute برای ارسال پارامترها استفاده کنید.
- نوع داده را در صورت نیاز explicit کنید (مثلاً PDO::PARAM_INT).
- اتصال با charset=utf8mb4 و ERRMODE_EXCEPTION را فراموش نکنید.

اگر تجربه‌ای در مهاجرت از mysql_* یا mysqli به PDO دارید یا سوالی هست، خوشحال می‌شم بشنوم و بحث کنیم.

منبع: مستندات رسمی PHP — PDO Prepared Statements

🔖 #PHP #پی_اچ_پی #php #pdo #security #sql_injection #prepared_statements

👤 Developix

💎 Channel: @DevelopixPHP