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

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

💎 @Developix
🚀 Developix.ir

📌 پشتیبانی و تبلیغات:
@DevelopixSupport
Download Telegram
در ‏PHP،‏ heredoc و nowdoc دو روش برای تعریف رشته‌های چندخطی هستند که می‌توانند برای نگهداری متن‌های طولانی یا متن‌هایی که شامل کاراکترهای ویژه هستند، بسیار مفید باشند. این دو روش تفاوت‌هایی دارند که در ادامه توضیح داده می‌شود.

‏Heredoc:
‏Heredoc یک روش است که به کمک علامت <<<EOT (می توان هرچیزی به جای EOT نوشت) باز و بسته می‌شود.
این علامت می‌تواند چند حرف یا یک کلمه دلخواه به عنوان نشانگر داشته باشد، (<<<EOT به عنوان مثال).
متن ‏Heredoc بین نشانگر شروع و نشانگر پایان آن قرار می‌گیرد. Heredoc امکان تفسیر متغیرها را دارد.

مثال:
$name = "John";
$text = <<<EOT
Hello $name,
This is a heredoc example.
EOT;

echo $text;

Output:
Hello John,
This is a heredoc example.

در این مثال، متغیر $name درون متن heredoc استفاده شده است و مقدار واقعی آن تفسیر و نمایش داده می‌شود.

———

‏Nowdoc:
‏Nowdoc به‌طور مشابهی به heredoc عمل می‌کند، با این تفاوت که نمی‌تواند متغیرها را درون خود تفسیر کند. Nowdoc با استفاده از علامت <<<'EOT' (می توان هرچیزی به جای EOT نوشت) شروع و تا علامت پایانی خود ادامه می‌یابد.

مثال:
$name = "John";
$text = <<<'EOT'
Hello $name,
This is a nowdoc example.
EOT;

echo $text;


Output:
Hello $name,
This is a nowdoc example.

در این مثال، $name درون nowdoc استفاده شده است، اما به عنوان رشته خام خوانده می‌شود، بنابراین نتیجه نهایی متن $name خواهد بود.

———

توجه داشته باشید که هر کاراکتری بدون محدودیت بین Hewedoc و Nowdoc میتواند قرار گیرید. به عنوان مثال:
$text = <<<EOT
*''
*/'
*"
EOT;

echo $text;


Output:
*''
*/'
*"


از Heredoc و Nowdoc می توان برای نوشتن تگ های HTML یا JS و ... که دارای کاراکتر های خاص مثال / " ' هستند استفاده کرد.

👤 AmirHossein

💎 Channel: @DevelopixPHP
👍12
در PHP، مفهوم variable variables یا متغیرهای متغیر به امکان تعریف و استفاده از متغیرهایی اشاره دارد که نام آن‌ها از مقدار یک متغیر دیگر تعیین می‌شود. این به شما امکان می‌دهد تا در زمان اجرا نام متغیرها را مشخص کنید.

  $Hello = "World";
$a = "Hello";

echo $a; // Hello
echo $$a; // World


در مثال یک متغیر به نام $Hello ایجاد شده و به آن رشته World اختصاص داده شده است. همچنین یک متغیر به نام $a ایجاد شده و به آن رشته Hello اختصاص داده شده است.
زمانی که از یک علامت $ استفاده کرده ایم مقدار متغییر $a نمایش داده میشود اما زمانی که از دو علامت $ استفاده شده به معنای متغیری است که نام آن برابر با مقدار $a است.
مقدار $a برابر Hello است، بنابراین $$a معادل با $Hello می‌شود. و مقدار $Hello برابر World است.

مثال :
فرض
کنید می‌خواهید یک سری متغیر با نام‌های متمایزی ایجاد کنید، اما نام آنها را از یک آرایه بگیرید. اینجاست که متغیرهای متغیر به کمک می‌آیند:
$variable_names = array("var1", "var2", "var3");
foreach ($variable_names as $name) {
$$name = rand(1, 100);
}

echo $var1;
echo $var2;
echo $var3;


در این مثال، ابتدا یک آرایه با نام‌های متغیرها ایجاد می‌شود. سپس با استفاده از حلقه foreach، برای هر نام متغیر در آرایه، یک متغیر با همان نام ایجاد می‌شود و به آن یک مقدار تصادفی از ۱ تا ۱۰۰ اختصاص داده می‌شود. در نهایت، مقادیر متغیرها با استفاده از نام آنها نمایش داده می‌شود.

شما می توانید به هر تعداد دلخواه $ در php قرار دهید (بر خلاف زندگی عادی):
echo $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$dontTryThisAtHome;


مثال:
  $Bar = "a";
$Foo = "Bar";
$World = "Foo";
$Hello = "World";
$a = "Hello";

$a; //Returns Hello
$$a; //Returns World
$$$a; //Returns Foo
$$$$a; //Returns Bar
$$$$$a; //Returns a

$$$$$$a; //Returns Hello
$$$$$$$a; //Returns World

//... and so on ...//


و حتی به صورت زیر:
$nameTypes    = array("first", "last", "company");
$name_first = "John";
$name_last = "Doe";
$name_company = "PHP";

foreach($nameTypes as $type)
print ${"name_$type"} . "\n";

print "$name_first\n$name_last\n$name_company\n";


با این حال در برخی موارد مانند Superglobal array ها مانند $_SERVER و متغیر $this که از متغیر های خاص هستند این قابلیت غیرقابل استفاده می باشد.

👤 AmirHossein

💎 Channel: @DevelopixPHP
6👍3🔥2
در PHP، رفرنس‌ها (References) امکان اشاره به محتوای متغیرها را بدون کپی‌برداری از آن‌ها فراهم می‌کنند. این ویژگی به خصوص در زمانی مفید است که می‌خواهیم تغییراتی را بر روی متغیرها در یک تابع یا بین بخش‌های مختلف برنامه اعمال کنیم بدون اینکه نیاز به بازگرداندن مقادیر باشد.

برای تعریف یک رفرنس، می‌توانیم از نشانه & استفاده کنیم. به مثال زیر توجه کنید:

$a = 10;
$b = &$a;

$b = 20;
echo $a; // Output: 20


در این مثال، متغیر $b به $a رفرنس دارد و هر تغییری در $b منجر به تغییر در $a نیز خواهد شد.

رفرنس‌ها را می‌توان در توابع برای تغییر متغیرهایی که به تابع پاس داده می‌شوند استفاده کرد. نمونه زیر این مورد را نشان می‌دهد:
function add_five(&$value) {
$value += 5;
}

$number = 10;
add_five($number);
echo $number; // Output: 15


در این مثال، تابع add_five متغیر $value را به عنوان رفرنس دریافت می‌کند و هر تغییری که در تابع بر روی این متغیر اعمال شود، در متغیر اصلی نیز منعکس می‌شود.

رفرنس‌ها همچنین می‌توانند در کار با آرایه‌ها بسیار مفید باشند، به خصوص وقتی که می‌خواهیم تغییراتی را در هر عنصر آرایه اعمال کنیم:
$numbers = [1, 2, 3, 4, 5];
foreach ($numbers as &$number) {
$number *= 2;
}

print_r($numbers); // Output: [2, 4, 6, 8, 10]


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

بعضی از توابع PHP که مقادیر را کپی می‌کنند (مانند array_map)، با رفرنس‌ها کار نمی‌کنند. در این موارد، تغییراتی که به عناصر آرایه اعمال می‌شوند، بر مقادیر اصلی تأثیری نمی‌گذارند.

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

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

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

👤 AmirHossein

💎 Channel: @DevelopixPHP
👍84
عملگرهای && , || , and , or همگی برای انجام عملیات‌های منطقی استفاده می‌شوند، اما بین آن‌ها تفاوت‌هایی در اولویت اجرا وجود دارد که می‌تواند بر روی نتیجه برنامه تأثیر بگذارد.

عملگر && بررسی می کند که هر دو مقدار true باشند.
عملگر and مانند && عمل می کند اما با الویت پایین تر.

عملگر || بررسی می کند که حداقل یکی از مقادیر true باشد.
عملگر or نیز مانند || عمل می کند اما با الویت پایین تر.

مثال AND:
$a = true;
$b = false;

$result = $a && $b; // false

$result = $a and $b; // true

در هر دو مثال بالا قرار است که بررسی شود هر دو مقدار true باشند، اما چرا خروجی ها متفاوت اند؟
زمانی که از عملگر && استفاده می شود، بررسی می شود که $a و $b برابر true باشند. چنانچه یکی از آنها true نبود خروجی false می شود.

اما همانطور که گفته شد عملگر and نسبت به && الویت اجرا پایین تری دارد، یعنی ابتدا $result برابر $a قرار می گیرد و سپس and $b اجرا می شود.
بیایید با استفاده از پرانتز دقیق تر نشان دهیم:
($result = $a) and $b;


مشخص است که $result برابر $a قرار گرفته است و $a هم برابر true است، در نتیجه and $b تاثیری در نتیجه نخواهد گزاشت و خروجی همان true است.
این مشکل را با گزاشتن پرانتز می توان حل کرد، چرا که پرانتز ها الویت های اجرا را تغییر می دهند:
$result = ($a and $b); // false


در مثال بالا ابتدا داخل پرانتز اجرا می شود و سپس $result برابر نتیجه می شود.

نتیجه می گیریم عملگر = سریع تر از and اجرا می شود درصورتی که && سریع تر از = اجرا می شود.

------

مثال OR:
$a = false;
$b = true;

$result = $a || $b; // true

$result = $a or $b; // false


در هر دو مثال بالا قرار است که بررسی شود حداقل یکی از مقادیر true باشند، اما چرا خروجی ها متفاوت اند؟
جواب سوال دقیقا مانند AND است.

زمانی که از عملگر || استفاده می شود، بررسی می شود که حداقل یکی از $a یا $b برابر true باشند. چنانچه هر دو آنها true نبود خروجی false می شود.

اما همانطور که گفته شد عملگر or نسبت به || الویت اجرا پایین تری دارد، یعنی ابتدا $result برابر $a قرار می گیرد و سپس or $b اجرا می شود.
بیایید با استفاده از پرانتز دقیق تر نشان دهیم:
($result = $a) or $b;


مشخص است که $result برابر $a قرار گرفته است و $a هم برابر false است، در نتیجه or $b تاثیری در نتیجه نخواهد گزاشت و خروجی همان false است.
این مشکل را با گزاشتن پرانتز می توان حل کرد، چرا که پرانتز ها الویت های اجرا را تغییر می دهند:
$result = ($a or $b); // true


در مثال بالا ابتدا داخل پرانتز اجرا می شود و سپس $result برابر نتیجه می شود.

نتیجه می گیریم عملگر = سریع تر از or اجرا می شود درصورتی که || سریع تر از = اجرا می شود.

------

بهتر است در استفاده از عملگر ها دقت کنیم تا باعث ایجا مشکل در برنامه نشویم.
ترجیحا از عملگرهای && و || به جای and و or استفاده کنید.

👤 AmirHossein

💎 Channel: @DevelopixPHP
9🔥6👍2
در PHP، عبارت match یک قابلیت نسبتاً جدید است که اولین بار در نسخه 8.0 معرفی شد. این عبارت برای جایگزینی ساختار switch استفاده می‌شود و به شما امکان می‌دهد مقادیر را به صورت اختصاصی مقایسه کنید.

در استفاده از match مقادیر را بر اساس === مقایسه می‌کند، در حالی که switch از مقایسه == استفاده می‌کند. این به این معناست که match دقیق‌تر است و تبدیل‌های خودکار نوع را انجام نمی‌دهد.
هر شاخه در match می‌تواند مستقیماً یک مقدار را برگرداند و نیازی به استفاده از return یا break نیست.

مثال:
$statusCode = 404;

$result = match ($statusCode) {
200, 201 => "OK",
301, 302 => "Redirect",
404 => "Not Found",
500 => "Server Error",
default => "Unknown status code"
};

echo $result; // Outputs: Not Found


در این مثال، یک متغیر به نام $statusCode داریم که مقدار آن 404 است. این مقدار نشان‌دهنده یک کد وضعیت HTTP است که معمولاً برای صفحاتی که یافت نشده‌اند به کار می‌رود. زمانی که $statusCode با یکی از کلید ها برابر باشد مقدار آن را بر میگرداند، و زمانی که با هیچ یک از کلید ها برابر نباشد مقدار default را بر می گرداند.

خروجی match را میتوان در لحظه return, echo یا درون متغییر ریخت:
return match ($statusCode) {
// ...
};

echo match ($statusCode) {
// ...
};

$result = match ($statusCode) {
// ...
};


بر خلاف switch-case که میتوان چندین خط را برای هر یک از حالات اجرا کرد در match تنها یک عمل قابل اجرا است:
switch (1){
case 1:
$a = 10;
$b = 20;
$c = 30;
echo 'hello';
echo 'bye';
return null;
}

match (1) {
1 => 'hello'
};


همانطور که می بینید 6 عمل درون switch-case اجرا شده، اما در match تنها یک خط قابل نوشتن است، اما چندین راه وجود دارد که در match چندین عمل را اجرا کنید.

1- می توانید برای هر حالت یک کلوژر بنویسید و خروجی match را درون متغییر بریزید و آن را اجرا کنید:
$do = match (1){
1=> function (){
echo 'hello';
echo 'bye';
return null;
}
};
$do();



2- میتوانید کلوژر را مستقیما درون match اجرا کنید:
match (1){
1=> (function (){
echo 'hello';
echo 'bye';
return null;
})()
};


3- می توانید یک تابع بنویسید و آن را به match بدهید:
function test(){
echo 'hello';
echo 'bye';
return null;
}

$do = match (1){
1=> test()
};


در نهایت match یک ابزار قدرتمند و مدرن برای جایگزینی switch در PHP است که به شما امکان می‌دهد کد خود را دقیق‌تر و خواناتر بنویسید.

👤 AmirHossein

💎 Channel: @DevelopixPHP
🔥12👍31
‏Attributes ها، ابزاری قدرتمند برای افزودن اطلاعات متا داده به کدهای PHP هستند. این قابلیت برای انواع مختلفی از کاربردها از جمله سریالایزیشن، ولیدیشن، کانفیگیوریشن دیپندنسی‌ها، و مشخص کردن روت‌های API مفید است.

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

اما شما می توانید اتریبیوت های خود را نیز بسازید، ابتدا باید یک Attribute را تعریف کنید. تعریف یک Attribute به سادگی تعریف یک کلاس است که با نماد #[Attribute] مشخص شده است. سپس، این Attribute را می‌توانید به کلاس‌ها، متدها، فانکشن‌ها، پراپرتی‌ها، یا حتی پارامترها اختصاص دهید.

فرض کنید می‌خواهیم یک Attribute برای تعریف نویسنده‌ی یک کلاس یا متد داشته باشیم:
#[Attribute()]
class Author {
public function __construct(public string $name) {}
}


در این مثال، Author یک Attribute است که نام نویسنده را دریافت می‌کند. این Attribute را می‌توان برای کلاس‌ها و متدها استفاده کرد.

حال، فرض کنید می‌خواهیم این Attribute را به یک کلاس و متد اختصاص دهیم:
#[Author("John Doe")]
class SampleClass {
#[Author("Jane Doe")]
public function exampleMethod() {}
}


برای دسترسی و استفاده از مقادیر تعریف شده توسط Attributes، می‌توانید از Reflection API استفاده کنید. این API به شما امکان می‌دهد در زمان اجرا اطلاعات را استخراج کنید.
$reflectionClass = new ReflectionClass(SampleClass::class);
$classAttributes = $reflectionClass->getAttributes(Author::class);

foreach ($classAttributes as $attribute) {
$authorInstance = $attribute->newInstance();
echo "Class Author: " . $authorInstance->name . "\n";
}

$reflectionMethod = $reflectionClass->getMethod('exampleMethod');
$methodAttributes = $reflectionMethod->getAttributes(Author::class);

foreach ($methodAttributes as $attribute) {
$authorInstance = $attribute->newInstance();
echo "Method Author: " . $authorInstance->name . "\n";
}


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

‏Attributes در PHP بر خلاف PHPDoc چیزی فراتر از کامنت‌ها هستند و به طور مستقیم توسط زبان تفسیر می‌شوند. در نسخه‌های قبلی PHP، توسعه‌دهندگان برای قرار دادن متادیتا به صورت کامنت‌هایی که به صورت دستی تفسیر می‌شدند (مانند PHPDoc) اتکا می‌کردند، اما Attributes در PHP 8 و بالاتر به گونه‌ای طراحی شده‌اند که به صورت بومی توسط زبان شناخته و مدیریت می‌شوند.

‏Attributes به شما این امکان را می‌دهند که اطلاعاتی را به اجزای مختلف کد مانند کلاس‌ها، توابع، پروپرتی‌ها، و پارامترها متصل کنید. این اطلاعات در زمان اجرا قابل استفاده هستند و می‌توانند توسط PHP و ابزارهایی که از Reflection API استفاده می‌کنند، خوانده شوند.

👤 AmirHossein

💎 Channel: @DevelopixPHP
👍7🔥1
‏PHPDoc یک ابزار مستندسازی برای زبان برنامه‌نویسی PHP است که از کامنت‌ها برای تولید مستندات فنی استفاده می‌کند. این ابزار به توسعه‌دهندگان امکان می‌دهد تا کدهای خود را به صورت خودکار و با استفاده از تگ‌ها و فرمت‌های خاص، مستندسازی کنند.

کامنت‌های PHPDoc با دو ستاره (/) آغاز می‌شوند و می‌توانند شامل تگ‌های مختلفی باشند که اطلاعات مهمی را در مورد توابع، کلاس‌ها، ویژگی‌ها و غیره ارائه می‌دهند. درمورد این تگ ها به طور کامل توضیح داده می شود.

نمونه کد:

/**
* Calculate the sum of two numbers.
*
* @param int $a first number
* @param int $b second number
* @return int The sum of two numbers
*/
function add($a, $b) {
return $a + $b;
}


کد بالا پارامتر ها و خروجی تابع را توضیح می دهد.

از آنجایی که PHPDoc ها کامنت هستند توسط PHP تفسیر نمی شوند به همین دلیل در زمان اجرا در دسترس نیستند و برای خواندن آنها باید از ابزار هایی مانند PHPDocumentor استفاده کنید، ولی IDE ها توان تفسیر آنها را دارا می باشند و اگر کتابخانه ای توسعه می دهید به استفاده کننده گان کمک می کنند.

بررسی تگ ها:
تگ های PHPDoc با @ شرع می شوند.

@api
نشان دهنده آن دسته از عناصر API است که عمومی تلقی می‌شوند.
class UserService
{
/**
* @api
*/
public function getUser() {}

/**
* This method is "package scope", not public-API.
*/
public function callMefromAnotherClass() {}
}


در مثال بالا متد GetUser به عنوان متد عمومی درون api مشخص شده در صورتی که متد دوم مربوط به api عمومی نیست.
———
@author [name] [<email address>]
مشخص کننده نویسنده کد.
/**
* @author John Doe <john@gmail.com>
*/


———
@category [description]
دسته‌بندی کلی کلاس یا توابع را مشخص می‌کند.
/**
* @category MyCategory
*/


———
@copyright [description]
متن حق کپی‌رایت را برای کد مشخص می‌کند.
/**
* @copyright Copyright 1994-2024 Acme Corporation
*/


———
@deprecated [<Semantic Version>] [<description>]
این تگ نشان می‌دهد که یک تابع یا کلاس دیگر استفاده نمی‌شود و ممکن است در نسخه‌های آینده حذف شود.
/**
* @deprecated 2.0 Use newFunction() instead.
*/
function oldFunction() {
}


———
@example [location] [<start-line> [<number-of-lines>] ] [<description>]
یک فایل نمونه که نحوه استفاده از کد را نشان می‌دهد.
/**
* @example /path/to/example.php
*/


———
@filesource
نشان می‌دهد که متن کامل فایل باید در مستندات نمایش داده شود.
<?php
/**
* @filesource
*/


———
@global [Type] [name]
@global [Type] [description]
توضیح می‌دهد که یک تابع به یک متغیر جهانی دسترسی دارد.
/**
* @global int $GLOBAL_VAR Description of global variable.
*/
function useGlobal() {
global $GLOBAL_VAR;
}


———
@ignore [<description>]
باعث می‌شود که ابزار مستندسازی یک عنصر خاص را نادیده بگیرد.
/**
* @ignore
*/
define("RUNTIME_OS","Windows");


———
@internal [description]
اطلاعاتی که فقط برای توسعه‌دهندگان داخلی استفاده می‌شود.
/**
* @internal This is only for advanced developers.
*/
function count() {}


———
@license [<url>] [name]
نوع لایسنس کد را مشخص می‌کند.
/**
* @license GPL
* OR
* @license https://opensource.org/licenses/gpl-license.php GNU Public License
*/


———
@link [URI] [<description>]
لینک به منبع مرتبط.
/**
* @link https://example.com More information here
*/


———
@method [[static] return type] [name]([[type] [parameter]<, ...>]) [<description>]
توصیف متد مجازی در کلاس، مفید برای کلاس‌هایی با متدهایی که با مجیک متد (__call) تعریف شده‌اند.
/**
* @method int magicMethod(string $param) Description
*/
class MyClass {}


———
@package [level 1]\\[level 2]\\[etc.]
تعریف بسته‌ای که کلاس یا تابع مرتبط با آن است.
/**
* @package Core
*/


———
@param [<Type>] [name] [<description>]
توصیف پارامترهای یک تابع.
/**
* @param int $a First number
* @param int $b Second number
*/
function add($a, $b) {
return $a + $b;
}


ادامه تگ ها در پست بعدی توضیح داده می شود.

👤 AmirHossein

💎 Channel: @DevelopixPHP
5👍2🔥1
ادامه تگ های PHPDoc:

@property[<-read|-write>] [Type] [name] [<description>]
توصیف ویژگی‌های مجازی در کلاس برای استفاده در میجک متد ها.
/**
* @property-read int $id The ID of the user
* @property string $name The name of the user
*/
class User {}


———
@return [Type] [<description>]
توصیف خروجی تابع.
/**
* @return float The calculated result
*/
function compute() {
// Implementation
}


———
@see [URI | FQSEN] [<description>]
ارجاع به دیگر عناصر مستند.
/**
* @see otherFunction() For basic functionality
*/


———
@since [<version>] [<description>]
نشان دهنده نسخه‌ای که عنصر خاصی در آن اضافه یا تغییر کرده است.
/**
* @since 1.0
*/


———
@source [<start-line> [<number-of-lines>] ] [<description>]
نمایش قسمتی از کد منبع.
/**
* @source 2 1 Check that ensures lazy counting.
*/
function count()
{
if (null === $this->count) {
// ...
}
}


———
@subpackage [name]
زیرمجموعه‌ای از بسته‌ای که به آن تعلق دارد.
/**
* @package PSR
* @subpackage Documentation\API
*/


———
@throws [Type] [<description>]
استثناء‌هایی که ممکن است تابع بدهد.
/**
* @throws Exception If the file cannot be opened.
*/
function openFile($filename) {
// Implementation
}


———
@todo [description]
کارهایی که باید در آینده انجام شوند.
/**
* @todo Implement the rest of the method.
*/


———
@uses [FQSEN] [<description>]
نشان دهنده استفاده از یک عنصر توسط دیگری.
/**
* @uses functionB() Used by functionA for processing.
*/


———
@var ["Type"] [element_name] [<description>]
توصیف نوع یک متغیر، مفید در متغیرهای کلاس.
/**
* @var string $name The name of the person
*/
protected $name;


———
@version [<Semantic Version>] [<description>]
نسخه کد یا کلاس.
/**
* @version 1.0.0
*/


👤 AmirHossein

💎 Channel: @DevelopixPHP
👍6
دستور 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