| AmirHossein | – Telegram
| AmirHossein |
592 subscribers
44 photos
8 videos
2 files
73 links
نوشته‌های یک برنامه‌نویس ناشی

🫂 @StartUnity
Download Telegram
استریم‌ ها در PHP - قسمت هفتم

- سایر استریم‌های ویژه

1- data://

این یک استریم رپر خاص است و به شما امکان می‌دهد داده‌های خام را به شکل یک URL داخلی در خود اسکریپت جاگذاری کنید.
با آن می‌توانید یک رشته داده (مثل متن یا حتی دادهٔ باینری به صورت Base64) را طوری استفاده کنید که گویی یک فایل است.

ساختار کلی آن به صورت
data://<MIME type>;base64,<encoded data>

یا
data://<MIME type>,<urlencoded data>

است.

موارد استفاده محدود ولی جالبی دارد؛ مثلاً برای تست و دمو می‌توانید به جای ایجاد یک فایل فیزیکی، محتوای آن را با data URI در خود کد قرار دهید. یا می‌توان از آن برای include کردن تکه کد PHP استفاده کرد.

به طور کلی، data:// زمانی به کار می‌آید که منبع داده شما از پیش در قالب یک رشته در دسترس است و می‌خواهید آن را مانند یک فایل رفتار دهید.

$quote = file_get_contents("data://text/plain;base64,SGVsbG8sIFdvcmxkIQ==");
echo $quote;

در اینجا از data:// با MIME type برابر text/plain و داده‌های Base64 استفاده کرده‌ایم.
رشته Base64 داده‌شده SGVsbG8sIFdvcmxkIQ== در واقع متن "Hello, World!" را نمایندگی می‌کند. با file_get_contents این منبع data URI را خواندیم و در خروجی چاپ کردیم؛ لذا نتیجه Hello, World! نمایش داده می‌شود.

همانطور که گفت شد، می توان یک کد PHP را به شکل Base64 تبدیل کرد، و آن را include کنیم.
include "data://text/plain;base64,PD9waHAgaGVhZGVyKCdDb250ZW50LVR5cGU6IHRleHQvcGxhaW4nKTtlY2hvICdIZWxsbyBXb3JsZCc7Pz4=";


لبته استفاده از data:// برای include مستلزم فعال بودن allow_url_include است و به لحاظ امنیتی همیشه توصیه نمی‌شود، اما وجود چنین امکانی بیانگر انعطاف بالای استریم‌ها در PHP است.

———
2- ssh2.xxx://

این استریم‌ها مربوط به دسترسی از طریق پروتکل Secure Shell (SSH2) هستند و در صورتی در دسترس‌اند که اکستنشن SSH2 بر روی PHP نصب باشد.

با ssh2.sftp:// می‌توان به سیستم فایل روی یک سرور از طریق SFTP دسترسی داشت،و با ssh2.scp:// امکان کپی فایل به/از سرور از طریق SCP فراهم است.
همچنین ssh2.shell:// و ssh2.exec:// و ssh2.tunnel:// برای مقاصد مختلفی مثل اجرای دستورات روی سرور راه دور، ایجاد تونل SSH و غیره وجود دارند.

اگر نیاز به تعامل با فایل‌ها یا اجرای دستورات روی یک سرور دیگر از طریق SSH دارید، این استریم‌ها کار را ساده می‌کنند. به عنوان مثال، برای خواندن یک فایل روی سرور B از اسکریپت PHP که روی سرور A اجرا می‌شود، می‌توان از
ssh2.sftp://user:pass@host:22/path/to/file

استفاده کرد.

$fp = fopen("ssh2.sftp://user:password@remote-server.com:22/home/user/remote.txt", "r");
$content = stream_get_contents($fp);
fclose($fp);

در این مثال فرضی، یک اتصال SFTP به سرور remote-server.com با نام‌کاربری و رمز داده‌شده برقرار می‌شود و فایل remote.txt خوانده می‌شود.

استفاده از این رپرها به شما امکان می‌دهد بدون نیاز به ابزار خارجی یا کتابخانهٔ اضافه، مستقیماً از توابع استریم PHP (مانند fopen و غیره) برای تعامل با SSH/SFTP بهره ببرید.

طبیعتاً برای اینکه این کار عمل کند باید افزونه SSH2 نصب و فعال باشد و اعتبارنامه‌های ورود صحیح باشند. در غیر این صورت، PHP این آدرس را نخواهد شناخت.

———
3- ogg://

این استریم رپر برای کار با داده‌های رسانه‌ای فرمت Ogg طراحی شده است. Ogg یک قالب کانتینر چندرسانه‌ای (معمولاً صوتی) است. پشتیبانی از ogg:// در PHP مستلزم نصب بودن کتابخانه/افزونهٔ مربوط به فرمت Ogg می‌باشد.

در عمل این مورد بسیار کمتر استفاده شده است، اما تصور کنید می‌خواهید جریان صوتی یک فایل OGG را پردازش یا پخش کنید. با ogg:// می‌توانید مستقیماً محتوا را خوانده و احتمالاً با فیلترهای مناسب decode کنید. به طور خلاصه، این رپر برای خواندن دادهٔ خام از درون فایل‌های .ogg (مثلاً استخراج جریان‌های صوتی) به کار می‌رود و برای اکثر توسعه‌دهندگان PHP کاربرد روزمره‌ای ندارد مگر در پروژه‌های خاص مالتی‌مدیا.

استفاده از ogg:// به طور مستقیم شاید ساده نباشد زیرا نیاز به دانستن ساختار درونی Ogg و به‌کارگیری فیلتر یا کتابخانه جهت تفسیر داده‌ها دارد. اما در سطح استریم، مثال کلی می‌تواند به شکل زیر باشد:
$fp = fopen("ogg://song.ogg", "r");

در اینجا $fp حاوی استریم رمزگذاری‌شده صوتی خواهد بود و برای تبدیل به صدای قابل پخش باید از توابع decode صوت (یا انتقال آن به پلیر مناسب) استفاده کرد.

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

#PHP #PHP_streams
@AmirhDeveloper
.
🍓5👍1🔥1
امروز ورژن 9.0 از Bot API تلگرام منتشر شد، و یکی از بزرگترین آپدیت هاش بود.
محوریت اصلی این آپدیت هم Business account ها بودن.

از این دو لینک می‌تونید تغییرات رو مشاهده کنید:
https://news.1rj.ru/str/BotNews/108

https://core.telegram.org/bots/api-changelog#april-11-2025

۱۷ تا متد جدید اضافه شده که به ربات‌های بیزنسی امکان مانوردهی بیشتری روی اکانت میده، از جمله استوری ها، گیفت‌ها و استارز.

از طرفی لایبرری Laraquest هم طبق معمول در دقایق اولیه با آخرین نسخه از Bot API همگام شده.

@AmirhDeveloper
.
🍓3🔥21
استریم‌ ها در PHP - قسمت هشتم

- سایر استریم‌های ویژه

4- expect://

این استریم توسط افزونه PECL Expect فراهم می‌شود و به شما امکان تعامل با فرآیند‌های شبه‌تعاملی (مانند شبیه‌سازی رفتار ابزار expect در لینوکس) را می‌دهد.

با expect:// می‌توانید یک دستور سیستم‌عامل را اجرا کنید که منتظر ورودی کاربر است و سپس به صورت برنامه‌نویسی با آن تعامل کنید (ارسال ورودی‌ها و خواندن خروجی‌ها)، گویی که یک کاربر پشت ترمینال نشسته است.

مثلاً فرض کنید می‌خواهید از داخل PHP یک اسکریپت Python را اجرا کنید که در حین اجرا چند سوال yes/no از کاربر می‌پرسد. با expect:// می‌توانید PHP را طوری برنامه‌نویسی کنید که به آن سوالات پاسخ بفرستد و خروجی را دریافت کند.

این یک مورد پیشرفته است و بیشتر در محیط‌های خاص DevOps یا تست خودکار ابزارهای خط فرمان استفاده می‌شود.

$fp = fopen("expect://ftp", "w+");
fwrite($fp, "open example.com\n");
fwrite($fp, "user myusername\n");
fwrite($fp, "pass mypassword\n");
while ($line = fgets($fp)) {
echo $line;
// ...
}
fclose($fp);

در این مثال فرضی، ما برنامه ftp را با استریم expect باز کرده‌ایم. سپس چند فرمان را به آن ارسال کردیم (باز کردن اتصال، فرستادن نام‌کاربری و رمز). با fgets نیز خروجی برنامه ftp را خط‌به‌خط می‌خوانیم و چاپ می‌کنیم.

طبیعتاً در یک اسکریپت expect واقعی، شما منطق اضافه‌تری می‌نویسید تا تشخیص دهید چه زمانی ftp منتظر ورودی است (مثلاً عبارت "Password:" در خروجی ظاهر شد تا سپس رمز را ارسال کنید).

افزونه expect این امکانات تطبیق الگو را فراهم می‌کند. این توانمندی بسیار قدرتمند است اما محدود به مواقع خاص و نیازمند نصب extension است.

———

تا این قسمت با تمامی استریم های پیشفرض PHP آشنا شده ایم.

در قسمت بعد به ساخت استریم ها اختصاصی و شخصی سازی شده خواهیم پرداخت.


#PHP #PHP_streams
@AmirhDeveloper
.
🍓32👍2
استریم‌ ها در PHP - قسمت نهم

- ساخت استریم رپر سفارشی


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

به عبارتی می‌توانیم یک Stream Wrapper سفارشی بسازیم و آن را با یک اسکیم (پروتکل) دلخواه (مثلاً myprot://) ثبت کنیم و سپس با توابع معمولی PHP مثل fopen() یا file_get_contents() به منابع سفارشی خود دسترسی داشته باشیم.

- مراحل ساخت Stream Wrapper سفارشی

ابتدا یک کلاس PHP تعریف می‌کنیم که متدهای لازم برای یک Stream Wrapper را پیاده‌سازی کند. این متدها شامل عملیات پایه‌ای مانند باز کردن، خواندن، نوشتن و ... روی منبع سفارشی هستند و با نام های خاص و از پیش تعیین شده پیاده سازی می شوند (در بخش بعد لیست کامل متدها توضیح داده خواهد شد).

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

پس از تعریف کلاس، باید آن را به PHP معرفی (ثبت) کنیم.
برای این کار از تابع stream_wrapper_register استفاده می‌شود.
پارامتر اول نام پروتکل (اسکیم) دلخواه ما به صورت رشته (مثلاً "myprot") و پارامتر دوم نام کلاس پیاده‌کننده‌ی آن پروتکل است.

اگر ثبت با موفقیت انجام شود، از این پس هر زمان که PHP با آدرسی به شکل myprot://... مواجه شود، به جای دسترسی مستقیم به فایل‌سیستم، متدهای کلاس ما را فراخوانی می‌کند. در صورت عدم موفقیت در ثبت (مثلاً اگر نام پروتکل تکراری باشد) این تابع مقدار false برمی‌گرداند.

پس از ثبت پروتکل سفارشی، می‌توانیم از آن دقیقاً مانند سایر پروتکل‌ها استفاده کنیم.
برای مثال، می‌توان با fopen("myprot://something", "r") یک منبع را باز کرد که منجر به اجرای متد stream_open (یکی از متدهای خاص و از پیشی تعیین شده) در کلاس ما می‌شود.

برای روشن‌تر شدن موضوع، یک مثال ساده در نظر بگیرید. فرض کنیم می‌خواهیم یک Stream Wrapper بنام var:// پیاده‌سازی کنیم که با آن بتوان داده‌ها را مستقیماً در یک متغیر PHP ذخیره و بازیابی کرد (نوعی استریم درون‌حافظه‌ای).
کلاس ما مثلاً VariableStream نام دارد و داده‌ها را در یک متغیر سراسری با نام مشخص ذخیره می‌کند:
class VariableStream {
function stream_open($path, $mode, $options, &$opened_path) {
$url = parse_url($path);
$this->varname = $url["host"];
$this->position = 0;
if (strpos($mode, 'w') !== false || strpos($mode, 'x') !== false || strpos($mode, 'c') !== false) {
$GLOBALS[$this->varname] = '';
}
return true;
}

function stream_read($count) {
$data = substr($GLOBALS[$this->varname], $this->position, $count);
$this->position += strlen($data);
return $data;
}

function stream_write($data) {
$left = substr($GLOBALS[$this->varname], 0, $this->position);
$right = substr($GLOBALS[$this->varname], $this->position + strlen($data));
$GLOBALS[$this->varname] = $left . $data . $right;
$this->position += strlen($data);
return strlen($data);
}

stream_wrapper_register("var", "VariableStream") or die("Failed to register protocol");

$myvar = "";
$fp = fopen("var://myvar", "r+");
fwrite($fp, "Hello\n");
fwrite($fp, "World\n");
fclose($fp);

var_dump($myvar);

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

در مثال بالا، ابتدا پروتکل var:// به کلاس VariableStream نگاشت شده است.

سپس متغیری به نام $myvar تعریف شده و با fopen("var://myvar", "r+") یک استریم خواندن/نوشتن روی آن باز می‌کنیم. این عمل باعث فراخوانی stream_open در کلاس می شود.

با fwrite در واقع متد stream_write کلاس فراخوانی می‌شود و داده را در متغیر ذخیره می‌کند.

در پایان fclose($fp) استریم را می‌بندد (که منجر به stream_close در کلاس می‌شود، هرچند در این مثال ما این متد را پیاده‌سازی نکرده‌ایم).

در نهایت خروجی به صورت زیر خواهد بود:
string(12) "Hello
World
"


همانطور که مشاهده می‌کنید، با استفاده از Stream Wrapper سفارشی، توانستیم عملیات فایل‌گونه (خواندن/نوشتن) را روی یک متغیر ساده انجام دهیم، گویی که یک فایل است.

در قسمت های بعد، تمامی متدهایی که می‌توان در یک Stream Wrapper سفارشی پیاده‌سازی کرد را معرفی کرده و کاربرد هر کدام را توضیح می‌دهیم.

#PHP #PHP_streams
@AmirhDeveloper
.
🔥3🍓21👍1
نمیدونم چرا ریپوزیتوری‌های گیت‌هاب من به‌جای گرفتن استار، استار از دست میده
🤣5
کاش یکبار هم بود برای ایران هرچیزی به‌جز تسلیت بگیم... 🖤
12🤔1💔1
سلام به همه،

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

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

لطفاً کارزار رو امضا کنید و برای دوستاتون هم بفرستید تا بیشتر دیده بشه.
لینک کارزار:
https://www.karzar.net/207226

ممنون از همتون ❤️

@Amirhdeveloper
.
10👍18👎1
بهترین کادو ای که تا به حال گرفتم ❤️😂
🔥8🤣2🍓21
قدرت‌ها می‌توانند تاریخ را تحریف کنند، اما نمی‌توانند حقیقت را برای همیشه خاموش کنند. #خلیج_فارس، حقیقتی است ریشه‌دارتر از دروغ‌هایی که با سیاست نوشته می‌شوند. این نام، میراث ماست و تا همیشه خواهد ماند.

Power can distort history, but it can never silence the truth. The #Persian_Gulf is a truth far deeper than any lie written by politics. This name is our legacy and it will endure forever.

🔍 ircf.space
@ircfspace
👍105🍓3🤣1🙉1
یک باگی که توی سایت های فروشگاهی می‌تونه پیش بیاد که توی سبد خریدها هست

فرض کنید یک محصول رو به تعداد 1 عدد میخری.
الگوریتم طوری هست که تعداد محصول در قیمت ضرب میشه و قیمت نهایی برای فروش مشخص میشه.
برخی سایت‌ها اعتبارسنجی‌ای برای این تعداد ندارن و من می‌تونم توی اون اینپوت مقدار 0.01 رو بفرستم و محصول رو با قیمت غیرمنطقی بخرم

فرض کنیم محصول 100,000 تومنی رو میخرم 1000 تومن

پس توی توسعه روی کوچک‌ترین ورودی ها هم اعتبارسنجی بذارید.

@AmirhDeveloper
.
👍9🔥2🍓2
🔰 احتمالا ورژن 3 فریم‌ورک LaraGram تا 25 خرداد ریلیز میشه.

🔵 اتفاقات زیادی توی این ورژن افتاده و بالاخره بعد دو ورژن یک ورژن استیبل هست که دیگه قرار نیست ساختار کد نویسی توی اون تغییر زیادی بکنه.

🔴 همونطور که قبلا گفته بودم، Console Kernel بهش اضافه شده که کامندهای زیادی رو در اختیارتون قرار میده برای راحتی کار با فریم‌ورک.

این کرنل توی ورژن های قبلی هم بوده، ولی صرفا یک کامند رو می تونست اجرا بکنه، ولی الان به شدت پیشرفته هست:

▫️ می تونید کامندها رو زمان‌بندی کنید برای اجرا
▫️ ایجاد چک‌باکس، دراپ‌داون، اینپوت، اسپینر و... توی محیط ترمینال
▫️ ساخت کامندهای اختصاصی
▫️تکیمل خودکار کامندهای ناقص
▫️ و .....

🔵 در ادامه قرار بود Http Kernel اضافه بشه برای مدیریت آپدیت‌های تلگرام و ارسال درخواست‌ها، ولی این اسم خیلی مناسب نبود و Bot Kernel جایگزین اون شد.
این کرنل وظیفه دریافت آپدیت ها و پردازششون رو داره.

از طرفی سیستم Listening کاملا مشابه Routing لاراول بازنویسی شده و ترکیب اون با Bot Kernel قابلیت های به شدت زیادی رو در اختیارتون قرار میده:

▫️ تمامی لیسنرها در ورژن های گذشته پا برجا هستن
▫️ امکان ایجاد middlewareها بر روی Listenerها
▫️ دریافت و پردازش پارامترها و اعمال شروط برای اعتبارسنجی
▫️ امکان نام‌دهی به Listenerها
▫️ امکان ریدایرکت از یک Listener به Listener دیگر
▫️ امکان Listener Model Binding، و استفاده از دیتابیس در Listenerها
▫️ امکان قفل‌ کردن و اعمال محدودیت بر Listenerها
▫️ امکان ایجاد Fallback Listener ها
▫️ و .....

❗️ تا این بخش شاهد تغییرات اساسی در این ورژن هستیم، اما هنوز به نصف قابلیت‌ها نرسیدیم.

⚜️ سیستم صف‌ها و Queue and Job اضافه شده که می‌تونید عملیات‌ها و تسک‌هاتون رو زمانبندی کنید و در پروسس‌های جداگانه اجرا بشن

⚜️ سیستم احراز هویت با میدولرهای مختلف برای بررسی سطوح دسترسی اضافه شده

⚜️ سیستم کش با 6 درایور مخلتف با امکانات و انعطاف پذیری بالا به همراه RateLimiter برای محدود کردن درخواست ها

⚜️ بازنویسی کامل و اختصاصی Eloquent ORM برای LaraGram با پشتیبانی از 5 دیتابیس مختلف

⚜️ سیستم Encryption و Hashing

⚜️ اضافه شدن FileSystem برای کار با فایل ها و فولدر ها

⚜️ اضافه شدن سیستم Logging

⚜️ اضافه شدن Process و Pipeline برای مدیریت پردازش ها

⚜️ اضافه شدن Redis Manager پیشرفته برای کار با Redis

⚜️ اضافه شدن سیستم Translation برای ساخت ربات های چند زبانی

و خب باز هم مونده،

⚜️ سیستم MultiBot Connection برای توسعه و کار با چند ربات به صورت همزمان

⚜️ سیستم Divider برای تقسیم وظایف بین چندین ربات

⚜️ سیستم Step Managment برای مدیریت Step ها

⚜️ موتور Temple8، برای تبدیل فایل های template به درخواست های تلگرام

⚜️ سیستم Validation برای اعتبارسنجی درخواست ها

⚜️ اضافه شدن ساپورت ها برای کار با زمان ها، رشته ها، اعداد و کالکشن ها

⚜️ اضافه شدن LaraGram Installer برای نصب ساده تر و حرفه ای تر

⚜️ استریم رپرهایی برای کار با هسته LaraGram اضافه میشه برای تعامل ساده تر با اون

⚜️ بازنویسی داکیومت به صورت کامل و حرفه ای

⚜️ همچنین اضافه شدن هلپر های مختلف برای کیبورد ها، تاپیک ها و...

🔴 سیستم های کش سرتاسر فریم‌ورک رو در بر گرفتن
پکیج‌ها، ایونت پ‌ها، سرویس‌ها، کانفیگ‌ها، لیسنرها کش میشن تا از پردازش‌های تکراری در پروداکشن جلوگیری بشه

🔵 و اینکه LaraGram یک فریم‌ورک هست، و شما می‌تونید برای اون پکیج بنویسید و مثل لاراول با استفاده از Providerها اون رو توی LaraGram استفاده کنید

❗️ و احتمالا کلی چیز دیگه که فراموش کردم.

🔱 از اونجایی که Bot Kernel به جای HTTP Kernel اضافه شد، پس می‌تونیم HTTP Kernel رو به عنوان قابلیت جدید به ورژن 4 برای آینده اضافه کنیم.

🔱 تمامی سرویس های LaraGram به ریپوزیتوری های جداگانه منتقل میشن و به صورت meta-package برای LaraGram نصب میشن

در نهایت استار دادن به ریپوزیتوری های گیت هاب مارا خوشحال می کند.

🔰LaraGram
🔰LaraGram Core
🔰Laraquest

♦️@AmirhDeveloper
.
🔥8🍓21👍1
خیلی وقته پست نذاشتم و واقعا سرم شلوغ بوده

متسفانه لاراول رو یکم وقت نمی‌کنم ولی حداقل بحث "استریم‌ ها در PHP" رو یکی دو قسمت مونده بفرستم تموم بشه
🍓9
استریم‌ ها در 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 #PHP_streams
@AmirhDeveloper
.
🔥5🍓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 #PHP_streams
@AmirhDeveloper
.
🍓9👍1
کاش می‌فهمیدم کدوم یکی از ممبر ها زیر پست ها اسپم می‌کنه
روانی شدم از بس بن کردم
🗿4
استریم‌ ها در 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 #PHP_streams
@AmirhDeveloper
.
🔥4🍓3👍1
حدود ۲۰ دقیقه منتظر بیلد یه برنامه بودم، آخرای کار برق رفت
🤣5💔4
| AmirHossein |
حدود ۲۰ دقیقه منتظر بیلد یه برنامه بودم، آخرای کار برق رفت
جدا چطور می‌فهمن که من دارم کامپایل می‌کنم تا برقو قطع کنن

سیستم ذغالیه، یه کامپایل ۱۰ دیقه طول میکشه
بعد صاف وسطش برق قطع میشه
🗿2
| AmirHossein |
درود به همه 🤝 دیشب حوصله م سر رفته بود و کاملا منطقی تصمیم گرفتم کتابخانه Laraquest که یک کتابخانه برای کار با ربات تلگرام به زبان PHP بود رو با زبان Go پیاده سازی کنم. تا امروز مشغولش بود و تونستم یک نسخه از اون رو تحت عنوان پکیجی برای Go توسعه بدم. - این…
دفعه قبلی که حوصله‌م سررفته بود نسشتم و پکیج Laraquest رو با زبان GoLang بازنویسی کردم و حاصلش شد Laraquest-Go.

ولی با خودم فکر کردم که شاید خیلی حوصله‌م سرنرفته بوده، در نتیجه اینبار بیشتر حوصله‌م سر رفت، و struct ها رو به PHP اضافه کردم.
نمی‌دونم اینبار به اندازه کافی حوصله‌م سر رفته بوده یا نه، ولی به نظر برای الان کافیه.

در نتیجه من الان یک PHP دارم که می‌تونم توش از struct استفاده کنم.
البته که اضافه کردن چیزی مثل structها به PHP به این سادگی ها نیست و هنوز کلی کار نیاز داره، مثلا الان با یک کلاس هیچ تفاوتی نداره جز محدودیت هاش.
یعنی توی این استراکت نمی‌تونیم مجیک‌متد استفاده کنیم، یا ارث‌بری داشته باشیم و...
ولی در نهایت مثل یک کلاس رجیستر میشه، که این یعنی هیچ تفاوتی با ساخت یک کلاس نداره و عملا وجودش بی‌فایده‌س.
به همین دلیل اگر حوصله‌م بازم سر رفت کمی بیشتر روش وقت میذارم و در کنار class_entryها، struct_entry هم اضافه می‌کنم که از کلاس‌ها کاملا جدا بشه و سبک تر.
و در نهایت سینتکس رو به صورت زیر تغییر می‌دم:
Square{1, 2}

اما در کل برای تفریح و کسب تجربه چیز جالبی بود.

@AmirhDeveloper
.
🔥11🍓1
این VPNهای ارزون قیمتی که توی کانال‌ها تبلیغ می‌کنند رو ازشون فرار کنید.

اکانت نامحدود فقط ۴۹ هزار تومن


چنین چیزهایی یا بعد یک هفته از کار میوفتن، یا اطلاعات رو شنود می‌کنند.
وگرنه چنین قیمتی برای VPN، اونم نامحدود اصلا منطقی نیست.

از جای معتبر و آشنا بخرید.
👍9🤣1🍓1