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

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

💎 @Developix
🚀 Developix.ir

📌 پشتیبانی و تبلیغات:
@DevelopixSupport
Download Telegram
دستور goto در PHP برای انتقال جریان اجرای برنامه به یک نقطه مشخص در کد استفاده می‌شود. این نقطه مشخص با یک برچسب (label) تعیین می‌شود. اگرچه استفاده از goto معمولاً توصیه نمی‌شود، زیرا می‌تواند کد را پیچیده و غیرقابل خواندن کند، اما در برخی موارد خاص می‌تواند مفید باشد.

دستور goto به این شکل نوشته می‌شود:
goto label;

label:
// Code to execute


مثال:
فرض کنید یک حلقه for داریم که در آن یک شرط خاص را بررسی می‌کنیم. اگر این شرط برقرار باشد، می‌خواهیم بلافاصله به یک بخش دیگر از کد بپریم و ادامه حلقه را نادیده بگیریم. مثال زیر را در نظر بگیرید:
for ($i = 0; $i < 10; $i++) {
if ($i == 5) {
goto end;
}
echo "Current value of i: $i\n";
}

end:
echo "Loop terminated because i equals 5.";


در این مثال، حلقه از 0 تا 9 اجرا می‌شود، اما وقتی مقدار $i به 5 می‌رسد، دستور goto end اجرا می‌شود و برنامه به برچسب end منتقل می‌شود. نتیجه این است که حلقه متوقف می‌شود و پیغام "Loop terminated because i equals 5." نمایش داده می‌شود.

استفاده از goto می‌تواند باعث کاهش خوانایی کد شود. اگر کد پیچیده و طولانی باشد، دنبال کردن جریان اجرای برنامه می‌تواند دشوار شود.

در بیشتر موارد، می‌توان از ساختارهای کنترلی دیگر مانند break، continue و return استفاده کرد که خواناتر و مناسب‌تر هستند.

مثال دیگر:
فرض کنید نیاز داریم یک فایل را بخوانیم و اگر به یک خط خاص برسیم، به یک بخش دیگر از کد بپریم:
$file = fopen("example.txt", "r");

if ($file) {
while (($line = fgets($file)) !== false) {
if (strpos($line, 'special keyword') !== false) {
goto specialProcessing;
}
echo "Reading line: $line";
}

fclose($file);
}

specialProcessing:
echo "Special processing for a line containing 'special keyword'.";


در اینجا، فایل example.txt خط به خط خوانده می‌شود و اگر خطی شامل کلمه کلیدی 'special keyword' باشد، جریان برنامه به برچسب specialProcessing منتقل می‌شود.

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

👤 AmirHossein

💎 Channel: @DevelopixPHP
👍15
⭕️ آموزش‌های عمومی PHP

💠 در این سری از آموزش‌های زبان PHP به موارد عمومی این زبان از جمله Enum ها و Closure ها و Arrow Function ها و سایر موارد مرتبط با زبان PHP پرداخته شده است.
🔥10👍5
قابلیت Type Declarations (تعیین نوع) به شما این امکان را می‌دهد که نوع متغیرها، پارامترهای تابع، مقادیر بازگشتی و ویژگی‌های کلاس را مشخص کنید. این کار به افزایش استحکام کد و جلوگیری از خطاهای احتمالی در زمان اجرا کمک می‌کند.

مثال:
// Property
public int $number;

// Const
public const int MAX_LIMIT = 100;

// Function and Method params:
function sum(int $a, int $b){}

// Return type:
function sum($a, $b): int {

}


انواع Type Declarations:

انواع پایه‌ای (Scalar Types):
این انواع، ساده‌ترین نوع‌ها در PHP هستند که شامل موارد زیر می‌شوند:

‏int برای اعداد صحیح (integer).
‏float برای اعداد اعشاری (floating-point numbers).
‏string برای رشته‌ها.
‏bool برای مقادیر بولی (true یا false).
‏false برای مقدار همیشه fasle.‏
‏true برای مقدار همیشه true.

function addNumbers(int $a, int $b): int {
return $a + $b;
}


انواع ترکیبی (Compound Types):
این نوع‌ها ترکیبی از انواع مختلف هستند:

‏array‏ برای آرایه‌ها.
‏object برای اشیاء.
‏callable برای تابع‌هایی که می‌توان آن‌ها را فراخوانی کرد (مانند closure ها، نام توابع به صورت رشته، و غیره).
‏iterable برای انواعی که قابل تکرار (iteration) هستند، شامل آرایه‌ها و اشیاء که از Traversable پیروی می‌کنند.

function getValues(array $input): iterable {
return new ArrayIterator($input);
}


انواع خاص (Special Types):
‏mixed نوعی که می‌تواند هر چیزی باشد. ‏
‏void برای توابعی که مقداری برنمی‌گردانند.
‏null برای مشخص کردن یک مقدار null.
‏never نوعی که نشان می‌دهد تابع هرگز برنمی‌گردد (معمولاً برای توابعی که با exit() یا پرتاب استثناها (Exception) خاتمه می‌یابند).

function doNothing(): void {
// This function does not return any value.
}

function terminate(): never {
exit("Terminating...");
}


انواع کلاس‌ها و اینترفیس‌ها (Class/Interface Types):
شما می‌توانید از نام کلاس‌ها یا اینترفیس‌ها به عنوان نوع پارامتر یا نوع مقدار بازگشتی استفاده کنید. این کار باعث می‌شود که پارامترها یا مقادیر بازگشتی باید از آن کلاس یا اینترفیس باشند.

class User {
// Class code
}

function setUser(User $user) : User{
// Operation on $user
}


انواع نال‌پذیر (Nullable Types):
با افزودن یک علامت ? قبل از نوع، می‌توانید یک نوع را نال‌پذیر کنید، به این معنا که مقدار می‌تواند از نوع مشخص شده یا null باشد.

function findUser(?int $id): ?User {
if ($id === null) {
return null;
}
// Search for the user and return the User object
}


انواع ترکیبی منطقی (Union Types):
می‌توانید از ترکیب چند نوع با استفاده از | استفاده کنید. این به شما اجازه می‌دهد که یک پارامتر یا مقدار بازگشتی بتواند یکی از چندین نوع مختلف باشد.

function processInput(int|string $input) {
if (is_int($input)) {
// Int processing
} else {
// String processing
}
}


انواع متقاطع (Intersection Types):
این نوع به شما اجازه می‌دهد که یک پارامتر یا مقدار بازگشتی ترکیبی از چندین نوع مختلف (همزمان) باشد. این نوع زمانی استفاده می‌شود که یک شیء باید همزمان از چندین اینترفیس پیروی کند.

function handleInput(A&B $input) {
// $input must be of type A and B at the same time.
}


‏self و parent و static :
‏self برای اشاره به کلاس فعلی.
‏parent برای اشاره به کلاس والد (در صورت وجود).
‏static به یک کلاس خاص اشاره کند، به کلاس فعلی یا کلاسی که از آن ارث‌بری شده است اشاره می‌کند.

class Base {
public function getClass(): static {
return $this;
}
}


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

👤 AmirHossein

💎 Channel: @DevelopixPHP
👍12🔥31
معرفی yield - قسمت دوم

در قسمت اول با مفهوم و کاربرد yield آشنا شده ایم، در این قسمت به طور کامل با انواع روش های استفاده از آن آشنا می شویم.

ابتدا به معرفی متد های تعامل با Generator ها آشنا می شویم:

1- متد key
کلید (index) فعلی Generator را برمی‌گرداند.
function gen() {
yield 'a';
yield 'b';
}

$generator = gen();
echo $generator->key(); // 0


2- متد current
مقدار فعلی را برمی‌گرداند.
echo $generator->current(); // a


3- متد next
‏Generator را به مقدار بعدی منتقل می‌کند.
$generator->next();
echo $generator->current(); // b


4- متد rewind
‏Generator را به ابتدای لیست برمی‌گرداند. فقط در صورت عدم اجرای کامل Generator کار می‌کند.
$generator->rewind();
echo $generator->current(); // a


5- متد valid
بررسی می‌کند که آیا مقدار فعلی معتبر است یا خیر.
if ($generator->valid()) {
echo "Valid";
}


6- متد send
مقداری را به Generator ارسال می‌کند (برای کار با Generators تعاملی مفید است).
function interactive() {
$value = yield;
echo "Received: $value\n";
}

$generator = interactive();
$generator->send('Hello!'); // Received: Hello!


7- متد throw
یک استثنا به Generator ارسال می‌کند.
function gen() {
try {
yield 1;
} catch (Exception $e) {
echo $e->getMessage();
}
}

$generator = gen();
$generator->throw(new Exception("Error")); // Error


8- متد getReturn
مقدار بازگشتی تابع Generator را (در صورتی که وجود داشته باشد) برمی‌گرداند. از PHP 7.0 اضافه شده است.
function gen() {
yield 1;
return 42;
}

$generator = gen();
foreach ($generator as $value) {
echo $value . "\n"; // 1
}

echo $generator->getReturn(); // 42


در ادامه به حالت های استفاده از yield خواهیم پرداخت:

1- حالت بازگشت مقدار ساده:
در ساده‌ترین حالت، yield مقداری را برمی‌گرداند که می‌توان در یک حلقه به آن دسترسی داشت.
function simpleYield() {
yield 1;
yield 2;
}

foreach (simpleYield() as $value) {
echo $value . " ";
}

// Output: 1 2


2- بازگشت مقدار به همراه کلید:
در حالت معمولی، yield یک مقدار را تولید می‌کند. اما می‌توان یک کلید نیز همراه با مقدار تولید کرد.
function keyValueYield() {
yield "a" => 1;
yield "b" => 2;
}

foreach (keyValueYield() as $key => $value) {
echo "$key: $value, ";
}

// Output: a: 1, b: 2,


3-‏ Yield ترکیبی با ارسال و دریافت مقادیر (send)
می‌توانید مقادیر را به generator ارسال کنید و نتیجه را دریافت کنید.
مثال این مورد برای متد شماره 6 در ابتدای پست آورده شده.


‏4- Yield همراه با Exception Handling
با استفاده از متد throw می‌توان یک استثنا به Generator ارسال کرد.
مثال این مورد برای متد شماره 7 در ابتدای پست آورده شده.

5- ‏Yield مقادیر از منابع خارجی (با استفاده از yield from)
‏yield from برای تولید مقادیر از یک منبع دیگر، مانند یک آرایه یا یک Generator داخلی، استفاده می‌شود.
این منبع میتواند یک آرایه یا یک Generator باشد.

‏Yield from یک آرایه
function arrayYield() {
yield from [1, 2, 3];
}

foreach (arrayYield() as $value) {
echo $value . " "; // 1 2 3
}


‏Yield from یک Generator
function subGenerator() {
yield 1;
yield 2;
}

function mainGenerator() {
yield from subGenerator();
yield 3;
}

foreach (mainGenerator() as $value) {
echo $value . " "; // 1 2 3
}


6- بازگشت مقدار نهایی
می‌توان مقدار نهایی تولید شده توسط Generator را پس از تکمیل، از طریق متد getReturn دریافت کرد.
مثال این مورد برای متد شماره 8 در ابتدای پست آورده شده.

7- ‏Yield بدون مقدار
اگر yield بدون مقدار استفاده شود، مقدار پیش‌فرض null بازمی‌گرداند.
function nullYield() {
yield;
yield 2;
}

foreach (nullYield() as $value) {
var_dump($value); // NULL 2
}


8- ‏Yield با Closure‌ها
می‌توان yield را همراه با Closure استفاده کرد تا مقادیر داینامیک ایجاد شوند.
function closureYield($callback) {
for ($i = 0; $i < 3; $i++) {
yield $callback($i);
}
}

$generator = closureYield(function ($n) {
return $n * 2;
});

foreach ($generator as $value) {
echo $value . " "; // 0 2 4
}


9- ‏Yield با Reference
‏Yield با Reference این امکان را می‌دهد که مقدار بازگردانده‌شده از Generator مستقیماً قابل تغییر باشد.
function &gen_reference() {
$value = 3;
while ($value > 0) {
yield $value;
}
}

foreach (gen_reference() as &$num) {
echo --$num . ' '; // 2 1 0
}


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

👤 AmirHossein

💎 Channel: @DevelopixPHP
4👍3
پراپرتی هوک ها (Property Hooks)

این ویژگی‌ در PHP 8.4 معرفی شده است که کنترل بیشتری روی نحوه خواندن و نوشتن ویژگی‌های کلاس فراهم می‌کند. این قابلیت، انعطاف‌پذیری بالایی در مدیریت رفتار ویژگی‌های کلاس به توسعه‌دهندگان می‌دهد.

- تعریف کلی
پراپرتی هوک ها به شما اجازه می‌دهند تا به صورت مستقیم رفتار خواندن و نوشتن یک ویژگی را با استفاده از متدهای خاص تنظیم کنید.
این ویژگی به شما امکان می‌دهد که بدون نیاز به استفاده از مجیک متدهای (مانند __get و __set) رفتار سفارشی برای ویژگی‌های خاصی تعریف کنید.

- ساختار استفاده
پراپرتی هوک ها با تعریف Getter و Setter به صورت مستقیم در تعریف ویژگی کلاس عمل می‌کنند. به‌جای تعریف ویژگی‌های ساده، شما از قالب زیر استفاده می‌کنید:
class ClassName {
public Type $propertyName {
get => /* Expressing the return code or value */;
set => /* Code expression for initialization */;
}
}


توضیح ساختار:

‏get => ...:
برای زمانی که ویژگی خوانده می‌شود.
$value = $object->propertyName;


می‌توانید یک مقدار ثابت، مقدار محاسبه‌شده، یا نتیجهٔ یک فراخوانی تابع را بازگردانید.

‏set => ...:
برای زمانی که به ویژگی مقدار اختصاص داده می‌شود.
$object->propertyName = 'value';


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

- مثال

فرض کنید یک کلاس داریم که نام کامل کاربر را مدیریت می‌کند.
می‌خواهیم نام کامل به صورت ترکیب firstName و lastName باشد، اما به جای تعریف متدهای جداگانه از پراپرتی هوک ها استفاده می‌کنیم.
class User {
public function __construct(
private string $firstName,
private string $lastName
) { }

public string $fullName {
get => "{$this->firstName} {$this->lastName}";
set => [$this->firstName, $this->lastName] = explode(' ', $value, 2);
}
}


استفاده و توضیح:
$user = new User('John', 'Doe');
echo $user->fullName; // John Doe

در اینجا، مقدار fullName از ترکیب firstName و lastName تولید شده است.

$user->fullName = 'Jane Doe';
echo $user->firstName; // Jane
echo $user->lastName; // Doe

مقدار fullName به دو بخش firstName و lastName تقسیم شده و در ویژگی‌های مربوطه ذخیره می‌شود.

- اعمال عملیات پیچیده تر
‏Getter و Setter می توانند به صورت چند خطی و مانند توابع پیاده سازی شوند تا عملیات های پیچیده تری را در هنگام Get و Set پراپتری ها انجام دهد.

مثال:
فرض کنید در یک کلاس، یک ویژگی age داریم، اما سن کاربر به صورت تاریخ تولد در دیتابیس ذخیره می‌شود. در این حالت:
‏getter باید تاریخ تولد را به سن تبدیل کند.
‏setter باید سن ورودی را به تاریخ تولد تبدیل و ذخیره کند.
class User {
private DateTime $birthDate;

public function __construct(DateTime $birthDate) {
$this->birthDate = $birthDate;
}

public int $age {
get {
$currentDate = new DateTime();
$age = $currentDate->diff($this->birthDate)->y; // تفاوت به سال
return $age;
}
set (int $value) {
$currentDate = new DateTime();
$this->birthDate = (clone $currentDate)->sub(new DateInterval("P{$value}Y"));
}
}
}


استفاده و توضیح:

‌‌‏getter (محاسبه سن):
مقدار تاریخ تولد که در ویژگی birthDate ذخیره شده است، با تاریخ فعلی مقایسه می‌شود.
اختلاف به سال‌ها محاسبه می‌شود و به‌عنوان سن کاربر بازگردانده می‌شود.
$user = new User(new DateTime('1990-01-01'));
echo $user->age; // 35


‏setter (محاسبه تاریخ تولد):
سن ورودی (مثلاً ۳۰) از تاریخ فعلی کسر می‌شود تا تاریخ تولد کاربر به‌دست آید.
مقدار محاسبه‌شده به ویژگی birthDate اختصاص داده می‌شود.
$user->age = 30;
echo $user->birthDate->format('Y-m-d'); // 1995-01-01


- کاربردهای پراپرتی هوک ها

1- محاسبات پویا: می‌توانید ویژگی‌هایی ایجاد کنید که مقدار آن‌ها به‌صورت پویا بر اساس شرایط محاسبه شود.
2- اعتبارسنجی داده‌ها: می‌توانید داده‌های ورودی را قبل از ذخیره‌سازی اعتبارسنجی کنید.
3- ساختارهای پیچیده: امکان تبدیل خودکار داده‌های ورودی به ساختارهای پیچیده‌تر وجود دارد.

- مقایسه با مجیک متدها

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

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

👤 AmirHossein

💎 Channel: @DevelopixPHP
👍52
قابلیت Asymmetric Visibility (دید نامتقارن)

این ویژگی از PHP 8.4 اضافه شده است و به شما امکان می‌دهد که سطح دسترسی‌های متفاوتی نوشتن (set) یک property تعریف کنید. در ادامه، به بررسی این قابلیت، نحوه استفاده، و مزایای آن خواهیم پرداخت.

در PHP نسخه‌های قبل از 8.4، سطح دسترسی propertyها به صورت ثابت و یکسان برای عملیات خواندن و نوشتن تعریف می‌شد. اما در بسیاری از موارد، نیاز بود که property:
1- قابل خواندن باشد اما قابل نوشتن نباشد یا برعکس.
2- برای خواندن عمومی و برای نوشتن محدود به کلاس یا ارث‌بری باشد.

برای حل این مشکل، ویژگی Asymmetric Visibility معرفی شد. این قابلیت به توسعه‌دهندگان اجازه می‌دهد تا دسترسی متفاوتی برای set یک property مشخص کنند.

- نحوه استفاده

برای استفاده از این ویژگی، می‌توانید در تعریف property‌ها از کلمه کلیدی جدید private(set) یا protected(set) استفاده کنید. این ترکیب مشخص می‌کند که نوشتن (set) یک پراپرتی یه محدودیت و سطح دسترسی دارد.

مثال:
class User {
public function __construct(
public private(set) string $username,
public protected(set) string $email,
protected private(set) int $age
) {}
}


در مثال بالا پراپرتی ها به ترتیب:
1- خواندن عمومی، نوشتن خصوصی
2- خواندن عمومی، نوشتن محدود به کلاس یا ارث‌بری
3- خواندن و نوشتن محدود به کلاس

- قوانین و محدودیت‌ها
1- این ویژگی فقط برای property‌هایی که نوع داده مشخص دارند قابل استفاده است.
public private(set) string $example; // Worked

public private(set) $example; // Error


2- نمی‌توانید سطح دسترسی setter را بازتر از getter تعیین کنید.
public private(set) string $prop; // Worked

private public(set) string $prop; // Error


3- ‏setter به صورت final است یعنی نمی‌توانید setter را در کلاس‌های فرزند بازنویسی کنید.
4- تعریف private(set) باید به صورت دقیق و بدون فاصله باشد؛ استفاده از private (set ) یا مشابه آن، منجر به خطا می‌شود.

- مزایا و کاربردها

1- به جای تعریف دستی getter و setter برای کنترل دسترسی، می‌توانید از این قابلیت به صورت مستقیم استفاده کنید.
2- با تفکیک سطح دسترسی خواندن و نوشتن، می‌توانید داده‌ها را در برابر تغییرات غیرمجاز ایمن‌تر کنید.
3- استفاده از Asymmetric Visibility، کد را کوتاه‌تر، خواناتر و قابل نگهداری‌تر می‌کند.

- استفاده در کلاس ارث‌بری
class Vehicle {
public protected(set) int $speed;
}

class Car extends Vehicle {
public function increaseSpeed(int $value): void {
$this->speed += $value; // Worked protected getter
}
}

$car = new Car();
$car->speed = 100; // Error protected setter
echo $car->speed; // Worked public getter


- نکته
شما فقط می‌توانید سطح دسترسی setter را تغییر دهید و چیزی به نام private(get) یا تغییر سطح دسترسی برای getter وجود ندارد.
به طور پیش‌فرض getter را با همان سطح دسترسی عمومی تعریف می‌کند که برای خود property تعیین شده است.
protected private(set) string $property;


ویژگی getter به صورت protected، و ویژگی setter به صورت private تعریف شده.

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

👤 AmirHossein

💎 Channel: @DevelopixPHP
👍73👎1
فضای نام (Namespace) در PHP یک قابلیت برای گروه‌بندی کلاس‌ها، توابع و ثابت‌ها است تا از تداخل نام (Name Collision) جلوگیری کند. مثل کشوهای یک کمد که هر کشو متعلق به دسته‌ای خاص است.

کاربردهای Namespace:
1- جلوگیری از تداخل نام کلاس/توابع/ثابت ها در پروژه‌های بزرگ.
2- سازماندهی کدها به صورت ماژولار.
3- امکان استفاده همزمان از کتابخانه‌های شخص ثالث بدون نگرانی از تداخل نام.
4-سازگاری با اتولودینگ استاندارد (مثل PSR-4).

مثال:
namespace App\Controllers;

class UserController {
public function index() {
return "User Dashboard";
}
}

در این مثال یک namespace با نام App\Controllers تعریف شده و کلاس UserController را در بر گرفته است.
حالا برای استفاده از UserController در یک فایل یا نیم اسپیس دیگر کافی است به صورت زیر عمل کنیم:

$user = new \App\Controllers\UserController();
echo $user->index();

این به این معنی است که کلاس UserController از نیم اسپیس App\Controllers فراخوانی شود.

کلمه کلیدی use:
کلمه کلیدی use به شما این امکان را می دهد تا یک بار، یک کلاس، از یک namespace را، use کنید و دفعات بعدی تنها نام کلاس را بدون namespace بنویسید:
use App\Controllers\UserController;

$user = new UserController();
echo $user->index();

این کار باعث کوتاهی و خوانایی کد در استفاده های مکرر از یک کلاس می شود.

نام های مستعار:
این ویژگی به شما این امکان را می دهد که یک کلاس را با نام مستعار use کنید:
use App\Controllers\UserController as UC;

$user = new UC();

این کد کلاس App\Controllers\UserController را با نام UC در دسترس قرار می دهد.

استفاده از چندین namespace در یک فایل:
به طور کلی تنها یک namespcae برای هر فایل توصیه می شود، اما PHP این امکان را می دهد که چندین namespace را در یک فایل بنویسید:
namespace Project1 {
class Logger { /* ... */ }
}

namespace Project2 {
class Logger { /* ... */ }
}

namespace { // Global space
$log1 = new Project1\Logger();
$log2 = new Project2\Logger();
}

خلاصه نویسی use ها:
در صورتی که چندین کلاس از یک namespace را نیاز دارید می توانید دستور use را به طور خلاصه تر بنویسید:
use App\Controllers\{UserController, OrderController};

استفاده در Autoloading:
با Namespaceها می‌توانید اتولودینگ را بر اساس ساختار فایل‌ها پیاده‌سازی کنید:
spl_autoload_register(function ($className) {
$path = str_replace('\\', '/', $className) . '.php';
require_once $path;
});

در این صورت ساختار پوشه های پروژه باید با namespace ها مطابقت داشته باشند، مثلا
# app/Controllers/UserController.php

namespace App\Controllers\UserController;
// ...

قوانین و محدودیت‌ها:
اعلام Namespace باید اولین خط کد (پس از <?php) باشد (به جز declare).
امکان تعریف چند Namespace غیر براکت‌دار در یک فایل وجود ندارد.

استفاده برای توابع و ثابت ها:
تمامی قوانین و موارد برای توابع و ثابت ها یکسان است با این تفاوت که برای use کردن توابع از کلمه کلیدی use function استفاده می شود:
namespace MyNamespace;

function test() {
echo "Test\n";
}

// Another File or Namespace:
use function MyNamespace\test;

test();

‏Namespace ها ابزاری ضروری برای مدیریت پیچیدگی در پروژه‌های PHP هستند. با استفاده از آن‌ها، کدتان تمیزتر، قابل نگهداری‌تر و حرفه‌ای‌تر خواهد شد.

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

👤 AmirHossein

💎 Channel: @DevelopixPHP
👍10👎1
خروجی حلقه کدام است؟

1️⃣ Error
2️⃣ 10 9 8 7 6 5 4 3 2 1
3️⃣ Warning
4️⃣ 9 8 7 6 5 4 3 2 1 0

پاسخ خود را همراه با توضیح ارائه دهید.

بدون اجرای کد یا استفاده از هوش مصنوعی، کمی فکر کنید.

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

👤 AmirHossein

💎 Channel: @DevelopixPHP
👍1👎1🔥1
| کانال توسعه‌دهندگان PHP |
خروجی حلقه کدام است؟ 1️⃣ Error 2️⃣ 10 9 8 7 6 5 4 3 2 1 3️⃣ Warning 4️⃣ 9 8 7 6 5 4 3 2 1 0 پاسخ خود را همراه با توضیح ارائه دهید. بدون اجرای کد یا استفاده از هوش مصنوعی، کمی فکر کنید. 🔖 #PHP, #پی_اچ_پی, #چالش 👤 AmirHossein 💎 Channel: @DevelopixPHP
🔰 در این سوال نکات زیادی حائز اهمیت است که معمولا در نظر گرفته نمی‌شود.

🔍 در ادامه، ساختار حلقه را به‌طور مفصل بررسی می‌کنیم:

for ($i = 10; $i--; $i > 0) {
    echo "$i ";
}


خروجی این حلقه به‌صورت زیر خواهد بود:
9 8 7 6 5 4 3 2 1 0

⁉️ اما چرا؟
بیایید ساختار حلقه را از ابتدا بررسی کنیم.

🔰 ساختار کلی حلقه for
حلقه for از سه بخش تشکیل شده است:

1- شروع: مقداردهی اولیه متغیر حلقه.
این بخش تنها یک بار در ابتدای حلقه اجرا می‌شود.

2- شرط ادامه: تعیین می‌کند که آیا حلقه ادامه یابد یا متوقف شود.
این بخش در هر تکرار، قبل از اجرای بدنه اجرا شده و شرط اجرای بدنه را بررسی می‌کند.

3- تغییر مقدار: مقدار متغیر حلقه را تغییر می‌دهد.
این بخش پس از اجرای بدنه حلقه اجرا می‌شود.

🔰 بررسی اجرای حلقه ذکر شده

1- مقداردهی اولیه:
- ابتدا متغیر $i مقدار 10 می‌گیرد و اجرای این بخش پایان می‌یابد.

2- بررسی شرط ($i--)
در این قسمت نکات مهمی وجود دارد:

- هر عدد به جز 0 مقدار true دارد، بنابراین تا زمانی که $i به 0 نرسد، حلقه ادامه خواهد داشت.

- در عبارت $i-- از عملیات post-decrement استفاده شده است، یعنی ابتدا مقدار فعلی $i برای بررسی شرط استفاده می‌شود، سپس مقدار $i کاهش می‌یابد.
- - به همین دلیل عدد 0 نیز چاپ خواهد شد.
- - مقدار $i بعد از کاهش وارد بدنه حلقه می‌شود، بنابراین چاپ اعداد از 9 شروع می‌شود.

اگر حلقه به این صورت نوشته می‌شد:
for ($i = 10; --$i; $i > 0) {
    echo "$i ";
}


در این حالت، ابتدا مقدار $i کاهش می‌یابد و سپس شرط بررسی می‌شود زیرا از عملیات pre-decrement، بنابراین 0 چاپ نمی‌شود و خروجی به این شکل خواهد بود:
9 8 7 6 5 4 3 2 1

3- بررسی قسمت سوم (تغییر مقدار update)
- بخش سوم این حلقه روی مقدار $i تغییری ایجاد نمی‌کند، بنابراین عملاً بی‌اثر است و می‌توان حلقه را ساده‌تر نوشت:
for ($i = 10; $i--;) {
    echo "$i ";
}


🔰 مرور روند اجرای حلقه ذکر شده

- مقدار دهی اولیه i با 10
- بررسی 10 == true، کاهش 10 به 9، چاپ 9
- بررسی 9 == true، کاهش 9 به 8، چاپ 8
‏.
‏.
‏.
- بررسی 2 == true، کاهش 2 به 1، چاپ 1
- بررسی 1 == true، کاهش 1 به 0، چاپ 0
- بررسی 0 == true، پایان حلقه

❗️ درک درست post-decrement ($i--) و pre-decrement (--$i) در حلقه‌ها اهمیت زیادی دارد و تفاوت‌های ظریفی در خروجی ایجاد می‌کند.

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

👤 AmirHossein

💎 Channel: @DevelopixPHP
🔥63👍2👎1
Forwarded from Developix Support
🥳مسابقۀ ۱۰۰ میلیونی ساخت بات در اپلیکیشن بله!🦾

💰 مسابقه‌ای برای ساخت بازو (بات) و مینی‌اپ در اپلیکیشن بله

🎯 از استعدادت پول در بیار!
چطوری؟

بله با مسابقهٔ «زور بازوت رو نشون بده!» یک فرصت عالی برای مهندسین نرم‌افزار، وب دولوپر‌ها، صاحبان سایت‌ها و اپلیکیشن‌ها و تیم‌های محصول فراهم کرده که پاسخگوی این دغدغه‌هاست.

🎁 یه مسابقه با ۱۰۰ میلیون تومن جایزهٔ نقدی و ۱ میلیارد تومن اعتبار تبلیغات منتظرته! ♨️

📎 همین الان در مسابقه ثبت‌نام کن! ➡️

💬
کانال اخبار بازو دراپلیکیشن بله

ک
انال اطلاع‌رسانی بله | @BaleMessenger
👎6👍4
استریم‌ ها در PHP - قسمت اول

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

به جای آنکه برای هر نوع منبع تابع‌ها یا روش‌های جداگانه‌ای داشته باشید، PHP با استفاده از استریم‌ها یک مجموعه توابع عمومی (مثل fopen, fread, fwrite و ...) فراهم کرده که با همه این منابع به شکل یکنواخت رفتار می‌کنند.

هر استریم رَپر (Stream Wrapper) در PHP در واقع یک پروتکل یا طرح (scheme) خاص را پیاده‌سازی می‌کند که به صورت scheme:// استفاده می‌شود. برای مثال، file:// برای دسترسی به سیستم فایل محلی، http:// برای منابع وب، یا php:// برای منابع داخلی PHP استفاده می‌شود.

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

- استریم‌های داخلی PHP

1- php://input

این استریم برای دسترسی به دادهٔ ورودی خام HTTP در PHP استفاده می‌شود. به طور خاص، این استریم محتوای خام بدنهٔ درخواست HTTP را (معمولاً در درخواست‌های POST یا PUT) ارائه می‌کند، بدون هیچ‌گونه پردازش یا parse خودکار.

زمانی که نیاز دارید ورودی خام درخواست را بخوانید (مثلاً دریافت داده‌های JSON از یک API کلاینت یا پردازش درخواست‌های RESTful)، این استریم بسیار مفید است. برخلاف متغیرهای سراسری مانند $_POST که فقط داده‌های form-urlencoded را می‌گیرند،
این استریم اجازه می‌دهد انواع داده‌ها (JSON, XML, متن خام و ...) را مستقیماً از بدنهٔ درخواست دریافت کنید.

$json = file_get_contents("php://input");
$data = json_decode($json, true);
echo "Hello " . $data["user"];

در این مثال، محتوای خام ورودی HTTP با file_get_contents از php://input خوانده شده و سپس از JSON به آرایه PHP تبدیل می‌گردد.
در نهایت نام کاربر خروجی گرفته می‌شود. اگر درخواست فوق رشتهٔ JSON
{"user": "Ali"}

را ارسال کرده باشد، خروجی برنامه Hello Ali خواهد بود.

توجه داشته باشید php://input فقط خواندنی است و فقط یک بار می‌توان محتوا را از آن خواند، یعنی پس از خواندن، محتوای آن خالی می‌شود. همچنین در مورد درخواست‌های معمولی فرم (مانند multipart/form-data برای آپلود فایل)، استفاده از این استریم توصیه نمی‌شود، زیرا PHP آن داده‌ها را قبلاً پردازش کرده است.
———
2- php://output

این استریم خروجی استاندارد اسکریپت PHP را نمایندگی می‌کند. هر داده‌ای که در آن نوشته شود، مستقیماً به خروجی معمول برنامه (همان چیزی که مرورگر دریافت می‌کند یا در CLI ترمینال نشان داده می‌شود) فرستاده می‌شود.
زمانی که بخواهید با توابع استریم داده‌ای را به خروجی بفرستید (به جای استفاده از echo یا print)، می‌توانید php://output را مانند یک فایل باز کرده و در آن بنویسید.

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

$fp = fopen("php://output", "w");
fwrite($fp, "Hello World!");
fclose($fp);

در این قطعه کد، ما استریم خروجی را باز کرده‌ایم و یک خط متن را با fwrite در آن نوشتیم. نتیجهٔ اجرای این کد نمایش متن ذکر شده در خروجی (مثلاً مرورگر یا کنسول) است. در واقع کاری که fwrite در اینجا انجام می‌دهد معادل همان echo کردن رشته‌ها است.

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

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

👤 AmirHossein

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

- استریم‌های داخلی PHP

3- php://stdin

این استریم نمایانگر ورودی استاندارد (STDIN) فرایند PHP است. در محیط خط فرمان (CLI)، php://stdin همان داده‌ای است که از کاربر یا از ورودی pipeline دریافت می‌شود.

در اسکریپت‌های PHP CLI که نیاز به خواندن ورودی کاربر از کنسول یا داده‌های piped از فرمان دیگر دارند، می‌توان این استریم را به کار برد. به عنوان مثال، برنامه‌ای که منتظر می‌ماند کاربر در ترمینال متنی وارد کند یا نتیجه اجرای یک دستور دیگر را از طریق pipe دریافت کند.

$fp = fopen("php://stdin", "r");
echo "Enter Your name: ";
$inputLine = fgets($fp);
echo $inputLine;
fclose($fp);

این اسکریپت ابتدا پیغام درخواست ورودی را در کنسول نمایش می‌دهد. سپس با fopen استریم را باز کرده و با fgets یک خط از آن می‌خواند (منتظر می‌ماند تا کاربر یک خط متن وارد کرده و Enter بزند). در نهایت همان خط را مجدداً در خروجی نمایش می‌دهد.

این استریم فقط خواندنی است و مخصوص محیط‌های تعاملی یا ورودی‌های خط فرمان می‌باشد (در حالت اجرای وب معمولاً کاربردی ندارد).
———
4- php://stdout

این استریم معادل خروجی استاندارد (STDOUT) در PHP است. در حالت CLI، هر چیزی که به php://stdout نوشته شود در کنسول به نمایش در می‌آید (مشابه عملکرد echo).

بیشتر در اسکریپت‌های خط فرمان کاربرد دارد، زمانی که بخواهید به صورت صریح به STDOUT بنویسید. هرچند در عمل استفاده مستقیم از php://stdout تفاوتی با php://output (در حالت CLI) ندارد، اما ممکن است برای شفاف‌سازی منظور یا برای کدنویسی سیستم‌هایی که مستقیماً با توصیف‌گرهای STDOUT کار می‌کنند، استفاده شود.

$fp = fopen("php://stdout", "w");
fwrite($fp, "Test message on STDOUT");
fclose($fp);

اجرای این کد در محیط خط فرمان، متن "Test message on STDOUT" را در خروجی ترمینال نمایش می‌دهد. این همان خروجی استاندارد برنامه است.

توجه کنید که در محیط وب (مثلاً اجرای PHP از طریق Apache یا Nginx)، STDOUT همان خروجی HTML ارسالی به مرورگر است، لذا php://stdout در آن context معادل php://output عمل می‌کند.
———
5- php://stderr

این استریم متناظر با خروجی خطا (STDERR) در PHP است. STDOUT و STDERR هر دو خروجی هستند اما به طور مجزا مدیریت می‌شوند؛ معمولاً STDOUT برای خروجی معمول برنامه و STDERR برای پیام‌های خطا یا لاگ خطاها استفاده می‌شود.

در اسکریپت‌های CLI یا محیط‌هایی که می‌خواهید پیام‌های خطا را جدا از خروجی معمول ارسال کنید. برای مثال، می‌توانید لاگ خطا یا هشدارها را به این استریم بنویسید تا در کنسول یا لاگ سرور به عنوان خطا ثبت شوند، بدون اینکه جریان عادی خروجی (STDOUT) را مختل کنند.

$fp = fopen("php://stderr", "w");
fwrite($fp, "Err: Not found!");
fclose($fp);

این قطعه کد در محیط خط فرمان، متن خطا را به STDERR می‌فرستد. در نتیجه اگر برنامه را اجرا کنید، پیغام "Err: Not found!" به عنوان خروجی خطا ثبت می‌شود (در ترمینال معمولاً با رنگ قرمز یا در جریان مجزا نمایش داده می‌شود).

در حالت وب، محتوایی که به آن نوشته شود توسط وب‌سرور ممکن است در لاگ خطای سرور ثبت گردد.
———
6- php://memory

این استریم یک فضای حافظه موقتی در RAM ایجاد می‌کند که می‌توان مانند یک فایل با آن رفتار کرد. تمام داده‌هایی که در php://memory نوشته می‌شوند، در حافظه RAM ذخیره می‌شوند. هنگامی که نیاز دارید یک رشته یا داده حجیم را موقتاً مانند یک فایل مدیریت کنید اما نمی‌خواهید روی دیسک نوشته شود.

برای مثال تولید محتوای پویا (مثل ایجاد یک فایل CSV در حافظه و سپس ارائه آن برای دانلود) یا جمع‌آوری خروجی‌های متعدد و سپس پردازش یا ارسال آن. مزیت استفاده از حافظه این است که عملیات سریع‌تر است (عدم نیاز به دیسک) البته به میزان حافظهٔ قابل دسترس PHP محدود است.

$fp = fopen("php://memory", "r+");
fwrite($fp, "Foo");
fwrite($fp, "Bar");

rewind($fp);
echo stream_get_contents($fp); // FooBar
fclose($fp);

در این مثال، ابتدا یک استریم حافظه باز می‌کنیم (r+ به معنی خواندن/نوشتن). سپس دو رشته "Foo" و "Bar" در آن نوشته می‌شود. با rewind مکان فایل را به ابتدای حافظه برمی‌گردانیم و با stream_get_contents کل محتوا را می‌خوانیم؛ حاصل رشتهٔ "FooBar" است که نشان می‌دهد داده‌ها با موفقیت در حافظه جمع‌آوری شده‌اند.

تمام این عملیات بدون نوشتن حتی یک بایت روی دیسک انجام شده است.

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

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

👤 AmirHossein

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

- استریم‌های داخلی PHP

7- php://temp

این استریم نیز رفتاری شبیه به php://memory دارد با این تفاوت که اگر حجم داده‌های نوشته‌شده از مقدار معینی بیشتر شود، به طور خودکار محتوا را در یک فایل موقت روی دیسک ذخیره می‌کند تا حافظه زیادی مصرف نشود (حد پیش‌فرض معمولاً ۲ مگابایت است).

مانند php://memory برای نگهداری موقت داده‌ها استفاده می‌شود، با این اطمینان که اگر داده خیلی بزرگ شد، به جای پر کردن RAM، به دیسک منتقل می‌شود.

این استریم برای مواردی مفید است که اندازهٔ داده از قبل مشخص نیست و ممکن است کوچک یا بسیار بزرگ باشد. شما می‌توانید بدون نگرانی از مدیریت دستی حافظه/دیسک، به سادگی داده‌ها را در php://temp بنویسید.

$fp = fopen("php://temp", "r+");
fwrite($fp, "temp data");
rewind($fp);
echo fgets($fp); // temp data
fclose($fp);

این کد رشته "temp data" را در استریم موقتی می‌نویسد و سپس با بازگشت به ابتدا، آن را می‌خواند و چاپ می‌کند. از آنجا که حجم این داده کم است، همه چیز در حافظه انجام می‌شود. اما اگر به جای یک رشتهٔ کوتاه، مثلاً چند مگابایت داده می‌نوشتیم، php://temp پس از عبور از آستانهٔ تعیین‌شده، به طور خودکار داده‌ها را در یک فایل موقت ذخیره می‌کرد.

این جزئیات برای برنامه‌نویس شفاف است و نیاز به تغییر کد نیست.

———
8- php://filter

این استریم امکان فیلتر کردن (پردازش) داده‌های ورودی یا خروجی را در حین خواندن/نوشتن فراهم می‌کند. در واقع php://filter خودش منبع نهایی داده نیست، بلکه لایه‌ای واسط است که می‌توانید آن را قبل از یک منبع دیگر قرار دهید تا داده‌ها را طی عملیات خواندن یا نوشتن تغییر دهد.

به عنوان مثال می‌توانید هنگام خواندن از یک فایل، تمام حروف را به بزرگ (uppercase) تبدیل کنید، یا هنگام نوشتن در یک فایل، داده‌ها را مثلاً به صورت Base64 کدگذاری کنید. این کار با تعریف فیلترهای موجود PHP مانند
string.toupper,
string.strip_tags,
convert.base64-encode
و غیره ممکن است.

$content = file_get_contents("php://filter/read=string.toupper/resource=input.txt");
echo $content;

در این مثال، ما از استریم فیلتر استفاده کرده‌ایم تا محتوای فایل input.txt را با فیلتر string.toupper (که همه حروف انگلیسی را به بزرگ تبدیل می‌کند) بخوانیم.

عبارت resource=input.txt در واقع به PHP می‌گوید منبع نهایی input.txt است اما قبل از تحویل داده، فیلتر string.toupper را بر داده‌های خوانده‌شده اعمال کن.

نتیجهٔ این کد نمایش محتوای فایل به صورت حروف بزرگ است، بدون اینکه نیاز باشد پس از خواندن، خودمان تابعی برای بزرگ‌کردن حروف صدا بزنیم. به همین شکل فیلترهای متنوعی برای حذف تگ‌های HTML، انکود/دیکود کردن Base64، فشرده‌سازی و... وجود دارد که می‌توان در php://filter به کار گرفت.

توجه داشته باشید که نحوه نگارش می‌تواند برای نوشتن نیز باشد
مثلاً
php://filter/write=<filter>/resource=<...>
هنگام fwrite و حتی می‌توان فیلترها را زنجیره‌ای اعمال کرد.

———
9- php://fd

این استریم امکان دسترسی مستقیم به یک توصیف‌گر فایل باز سیستم‌عامل (file descriptor) را فراهم می‌کند. در محیط‌های یونیکس، هر فرایند مجموعه‌ای شماره‌گذاری‌شده از توصیف‌گرهای فایل دارد:
0 برای STDIN
1 برای STDOUT
2 برای STDERR
و اعداد بالاتر برای فایل‌ها یا سوکت‌های باز.

با استفاده از
php://fd/<number>
می‌توان به توصیف‌گر مربوطه در PHP دسترسی گرفت.

این قابلیت نسبتاً خاص است و عمدتاً در اسکریپت‌های CLI یا موارد خیلی پیشرفته استفاده می‌شود. برای مثال اگر PHP توسط یک فرایند دیگر با توصیف‌گرهای اضافی فراخوانی شود (مثلاً descriptor 3 به یک فایل خاص اشاره کند)، می‌توان از php://fd/3 برای دسترسی به آن استفاده کرد. یا جهت تأیید، php://fd/1 اساساً خروجی استاندارد و معادل php://stdout است.

$fp = fopen("php://fd/1", "w");
fwrite($fp, "Test via FD 1\n");
fclose($fp);

در اینجا با بازکردن php://fd/1، مستقیماً به خروجی استاندارد نوشته‌ایم؛ این کار همان اثر php://stdout را دارد.

در عمل شما ممکن است کمتر مستقیماً از php://fd استفاده کنید مگر در شرایط خاص، زیرا PHP معادل‌های راحت‌تری برای STDIN/STDOUT/STDERR دارد. اما دانستن وجود آن برای موارد پیچیده (یا مثلاً تعامل با کتابخانه‌هایی که descriptorها را مدیریت می‌کنند) خالی از لطف نیست.

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


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

👤 AmirHossein

💎 Channel: @DevelopixPHP
🔥6👍21👎1
استریم‌ ها در PHP - قسمت چهارم

- استریم‌های سیستم فایل (File Streams)

1- file://

این استریم امکان دسترسی به سیستم فایل محلی سرور را فراهم می‌کند. file:// در PHP پیش‌فرض‌ترین استریم است؛ یعنی حتی اگر هیچ پروتکلی قبل از مسیر فایل ننویسید و مستقیم مسیری را بدهید، در واقع از همین پروتکل فایل استفاده می‌شود.

با file:// می‌توانید فایل‌های روی دیسک محلی را بخوانید، بنویسید، ایجاد کنید یا تغییر نام دهید – درست مانند کاری که با توابع معمول فایل انجام می‌دهید.

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

$data = file_get_contents("file://example.txt");
echo $data;

در این مثال، تابع file_get_contents را با مسیر file://... صدا زده‌ایم تا محتوای فایل example.txtخوانده شود.

استفاده از file:// در اینجا اختیاری است؛ زیرا اگر به جای آن مستقیماً مسیر فایل را می‌نوشتیم (مثلاً "example.txt")، PHP به صورت خودکار از استریم فایل استفاده می‌کرد.

توجه داشته باشید برای اشاره به مسیرهای مطلق در سیستم‌عامل ویندوز، سه اسلش بعد از file: لازم است .
مثال:
file:///C:/path/to/file.txt


———
2- glob://

این استریم رپر امکان استفاده از الگوهای glob را به شکل یک منبع داده فراهم می‌کند. به طور معمول، تابع glob() در PHP رشته‌های مسیر را بر اساس الگو (pattern) تطبیق داده و لیستی از نام فایل‌ها را برمی‌گرداند. glob:// این قابلیت را در قالب یک استریم پیاده‌سازی می‌کند که می‌توان آن را مانند یک دایرکتوری مجازی پیمایش کرد.

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

if ($dir = opendir("glob://*.txt")) {
while (($file = readdir($dir)) !== false) {
echo "Found: $file\n";
}
closedir($dir);
}

در این قطعه کد، از opendir با مسیر glob://*.txt استفاده کرده‌ایم. نتیجهٔ این opendir مثل این است که یک دایرکتوری باز کرده باشیم که فقط شامل فایل‌هایی است که با الگوی *.txt تطابق دارند. سپس با readdir در یک حلقه، تک‌تک نام این فایل‌ها را می‌خوانیم و چاپ می‌کنیم. در نهایت closedir را فراخوانی می‌کنیم.

استفاده از glob:// می‌تواند کدنویسی را در شرایطی که می‌خواهید روی مجموعه‌ای از فایل‌های منطبق با الگو کار کنید ساده‌تر کند.

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


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

👤 AmirHossein

💎 Channel: @DevelopixPHP
🔥53👍1👎1
استریم‌ ها در PHP - قسمت پنجم

- استریم‌های شبکه‌ای (HTTP و FTP)

1|2- http:// and https://

این استریم رپر برای دسترسی به منابع از طریق پروتکل HTTP (و HTTPS) به کار می‌رود. با استفاده از آن می‌توانید در PHP محتوای یک صفحه وب، API یا هر URL اینترنتی را مستقیماً بخوانید یا حتی داده‌ای را به آن ارسال کنید.

نکته: در حالت ارسال داده، معمولاً بهتر است از توابع مخصوص HTTP یا کتابخانه‌های وب استفاده شود، اما خواندن مستقیم رایج است.

متداول‌ترین کاربرد آن دریافت محتوای وب از داخل PHP است. برای مثال، خواندن خروجی یک API خارجی، واکشی محتوای یک صفحه وب جهت parse کردن، یا حتی دانلود یک فایل از اینترنت از طریق PHP.

$homepage = file_get_contents("http://www.example.com");
echo $homepage;

این کد با استفاده از file_get_contents محتوای خام HTML صفحه example.com را دریافت کرده و آن را echo می‌کند. در نتیجه HTML آن وب‌سایت (که شامل یک عنوان "Example Domain" و متن نمونه است) در خروجی ظاهر می‌شود.

همان‌طور که اشاره شد، https:// نیز پشتیبانی می‌شود و استفاده از آن مشابه http:// است.

———
3|4- ftp:// and ftps://

این استریم برای دسترسی به فایل‌ها و پوشه‌ها از طریق پروتکل FTP به کار می‌رود. شما می‌توانید با آن به یک سرور FTP متصل شوید، فایل بخوانید یا بنویسید، و حتی فهرست فایل‌ها را مرور کنید.

نسخهٔ امن FTP یعنی FTPS (FTP over SSL) نیز با پیشوند ftps:// در دسترس است، مشروط بر اینکه کتابخانه‌های لازم (مانند OpenSSL) فعال باشند.

کاربرد آن در دریافت یا ارسال فایل از/به یک سرور FTP از طریق PHP. برای مثال، اسکریپتی که هر شب یک فایل پشتیبان را از سرور دیگری دانلود می‌کند، یا سرویسی که یک فایل آپلودشده را روی FTP دیگری ذخیره می‌کند و... .

$data = file_get_contents("ftp://speedtest.tele2.net/1KB.zip");
file_put_contents("local_test.zip", $data);

در این مثال، به یک FTP عمومی متصل می‌شویم که یک فایل تست 1KB ارائه می‌دهد. با file_get_contents محتوای فایل باینری 1KB.zip را از طریق FTP دریافت کرده و سپس آن را با file_put_contents در یک فایل محلی (local_test.zip) ذخیره می‌کنیم.

در صورتی که FTP نیاز به احراز هویت داشت، باید در URL لحاظ شود، مثلاً:
ftp://username:password@ftp.example.com/pub/file.txt


برای نوشتن فایل در FTP نیز می‌توانید از fopen با مود w یا fwrite استفاده کنید، مشابه کار با فایل محلی، فقط باید دسترسی نوشتن روی سرور FTP داشته باشید.

- استریم‌های فشرده‌سازی و آرشیو

1|2- compress.zlib:// and compress.bzip2://

این رپر‌ها امکان فشرده‌سازی یا بازکردن داده‌ها را به صورت شفاف فراهم می‌کنند. compress.zlib:// در واقع برای کار با جریان‌های فشرده به فرمت gzip/zlib استفاده می‌شود و compress.bzip2:// برای فرمت BZip2.

شما با این استریم‌ها می‌توانید مستقیماً یک فایل فشرده (مثلاً یک فایل .gz یا .bz2) را باز کرده و محتوای غیرفشرده‌شدهٔ آن را بخوانید، یا بالعکس هنگام نوشتن، داده‌ها را به صورت فشرده ذخیره کنید.

خواندن فایل‌های متنی یا داده‌هایی که با gzip یا bzip2 فشرده شده‌اند بدون نیاز به اجرای دستی ابزارهای فشرده‌سازی. برای مثال، اسکریپتی که باید محتوای یک فایل لاگ فشرده‌شده را بخواند، می‌تواند مستقیماً آن را با compress.zlib:// باز کند. همچنین برای ساخت خروجی‌های فشرده (مثلاً ایجاد فایل CSV و ذخیره آن به صورت gzip) می‌توان در مسیر نوشتن از این رپر استفاده کرد.

توجه داشته باشید که استفاده از این استریم‌ها نیازمند فعال بودن کتابخانه‌های مربوطه در PHP است (zlib معمولاً به صورت پیش‌فرض وجود دارد، bzip2 نیز در بسیاری از توزیع‌ها فعال است).

$compressedFp = fopen("compress.zlib://logs_2025-04-03.txt.gz", "r");
$line = fgets($compressedFp);
echo $line;
fclose($compressedFp);

فرض کنیم فایلی به نام logs_2025-04-03.txt.gz داریم که با gzip فشرده شده است. در این مثال با fopen و پیشوند compress.zlib:// آن را باز می‌کنیم. سپس با fgets یک خط از محتوای غیرفشرده‌شده را می‌خوانیم و نمایش می‌دهیم. PHP به طور خودکار داده‌ها را از حالت فشرده خارج می‌کند، بنابراین نیازی نیست ابتدا فایل را دستی gunzip کنید.

استفاده از compress.bzip2:// نیز دقیقاً به همین شکل است، با این تفاوت که فشرده‌سازی با الگوریتم BZip2 انجام می‌شود و معمولاً برای فایل‌های .bz2 به کار می‌رود.

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

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

👤 AmirHossein

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

- استریم‌های فشرده‌سازی و آرشیو

3- zip://

این استریم رپر اجازه می‌دهد محتویات یک فایل ZIP را مانند یک سیستم فایل مجزا مشاهده و دستکاری کنید. با آن می‌توانید فایل‌های درون یک آرشیو ZIP را بخوانید بدون آنکه نیاز باشد کل آرشیو را دستی از حالت فشرده خارج کنید. برای اشاره به یک فایل داخل ZIP، از علامت # در مسیر استفاده می‌شود.

فرض کنید یک آرشیو zip حاوی چند فایل CSV دارید و می‌خواهید یکی از آنها را مستقیماً پردازش کنید؛ با zip:// می‌توانید مستقیماً آن فایل CSV را باز کنید. یا برای لیست کردن محتویات آرشیو می‌توانید مانند یک دایرکتوری عمل کنید.

توجه داشته باشید که این قابلیت نیازمند فعال بودن اکستنشن Zip در PHP است.

$content = file_get_contents("zip://". __DIR__ . "/archive.zip#readme.txt");
echo $content;

در اینجا با استفاده از file_get_contents به مسیر zip://.../archive.zip#readme.txt دسترسی پیدا کرده‌ایم. بخش قبل از # مسیر آرشیو ZIP روی دیسک را مشخص می‌کند و بعد از # نام فایلی داخل آن آرشیو را.

آرشیو را باز کرده، به فایل readme.txt درون آن دسترسی پیدا می‌کند و محتوایش را برمی‌گرداند. به همین ترتیب می‌توان هر فایلی را داخل ZIP با fopen یا حتی include (برای فایل‌های PHP داخل phar/zip) باز کرد.

این رپر فقط خواندن را پشتیبانی می‌کند؛ برای نوشتن به ZIP باید از کلاس‌های شیءگرای ZipArchive استفاده کنید.

———
4- phar://

‏Phar مخفف "PHP Archive" است و یک قالب آرشیو مخصوص PHP (معمولاً با پسوند .phar) می‌باشد که می‌تواند شامل فایل‌های PHP، کتابخانه‌ها و سایر منابع باشد. استریم phar:// اجازه می‌دهد فایل‌های داخل یک آرشیو Phar را همانند Zip به صورت شفاف بخوانید و حتی اجرا (include/require) کنید.
این قابلیت به توزیع و استفاده از برنامه‌ها یا کتابخانه‌های PHP در قالب یک فایل واحد کمک می‌کند.

برای مثال، Composer خودش به صورت یک فایل phar توزیع می‌شود که شما می‌توانید آن را با PHP اجرا کنید. با phar:// می‌توانید به محتویات آن دسترسی داشته باشید.

همچنین از این طریق می‌توان کد PHP را مستقیماً از Phar include کرد. نوشتن در Phar نیز ممکن است (Pharها می‌توانند در حالت قابل نوشتن باز شوند) اما معمولاً Pharها به صورت فقط خواندنی در برنامه‌ها استفاده می‌شوند.

require "phar://package.phar/lib/functions.php";

در این مثال، فایل lib/functions.php واقع در داخل آرشیو package.phar مستقیماً بارگذاری (require) شده است. یعنی حتی بدون اینکه آن را از آرشیو روی دیسک استخراج کنیم، PHP قادر است محتویاتش را تفسیر و اجرا کند.

از دید برنامه‌نویسی، این کار تفاوتی با require کردن یک فایل عادی ندارد، جز اینکه داریم از یک بستهٔ Phar می‌خوانیم. اگر بخواهیم محتوای غیر PHP (مثلاً یک فایل متنی) را از Phar بخوانیم، می‌توانیم از file_get_contents("phar://...") یا روش‌های مشابه استفاده کنیم.

———
5- rar://

این استریم رپر عملکردی مشابه zip:// دارد اما برای فرمت آرشیو RAR استفاده می‌شود. فایل‌های RAR به صورت پیش‌فرض توسط PHP پشتیبانی نمی‌شوند مگر اینکه اکستنشن RAR فعال شده باشد.

$fp = fopen("rar://files.rar#doc.txt", "r");
$content = stream_get_contents($fp);
fclose($fp);

این کد فرضی نشان می‌دهد که چگونه می‌توان از rar:// استفاده کرد. مانند Zip، پس از علامت # نام فایل درون آرشیو را مشخص می‌کنیم. با fopen و خواندن محتوا، PHP آرشیو را باز کرده و داده‌های فایل doc.txt را به ما می‌دهد.

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

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

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

👤 AmirHossein

💎 Channel: @DevelopixPHP
🔥5👍21👎1
استریم‌ ها در 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, #پی_اچ_پی

👤 AmirHossein

💎 Channel: @DevelopixPHP
🔥2👎1
استریم‌ ها در 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, #پی_اچ_پی

👤 AmirHossein

💎 Channel: @DevelopixPHP
🔥3👎1
استریم‌ ها در 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, #پی_اچ_پی

👤 AmirHossein

💎 Channel: @DevelopixPHP
🔥31👎1
استریم‌ ها در 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