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

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

💎 @Developix
🚀 Developix.ir

📌 پشتیبانی و تبلیغات:
@DevelopixSupport
Download Telegram
کلاس های readonly در PHP به شما اجازه می‌دهد ویژگی‌هایی در کلاس‌ها تعریف کنید که فقط می‌توانند در زمان ساخت شیء مقداردهی اولیه شوند و پس از آن، تغییرناپذیر هستند. این ویژگی برای تعریف کلاس‌هایی که داده‌های آن‌ها نباید تغییر کنند، بسیار مفید است. به این ترتیب، readonly در PHP، شما را قادر می‌سازد تا ویژگی‌های فقط‌خواندنی در کلاس‌هایتان داشته باشید.

نحوه تعریف:
یک کلاس readonly با استفاده از کلمه کلیدی readonly قبل از کلمه class در تعریف کلاس ایجاد می‌شود:
readonly class MyClass
{

}

کاربردها:
کلاس
‌های Read-Only به شما اجازه می‌دهند که اشیاء‌ای با ویژگی‌هایی که فقط برای خواندن هستند، ایجاد کنید. این ویژگی به ویژه برای مواردی مفید است که می‌خواهید اطمینان حاصل کنید داده‌های یک شیء پس از ایجاد آن، تغییر نکنند. این موضوع می‌تواند در برنامه‌نویسی نرم‌افزار برای محافظت از داده‌ها و جلوگیری از تغییرات ناخواسته مفید باشد.

تفاوت ها با کلاس عادی:
1- پراپرتی ها در کلاس های readonly نمیتوانند مقداردهی شوند یا مقدار انها را حذف کرد:
 readonly class MyClass { /* … */ }

$myClass = new MyClass(/* … */);

// Error :Cannot declare dynamic properties in 'readonly' class
$myClass->title = 'other';
unset($myClass->title);


2- تعریف پراپرتی ها در کلاس readonly تنها با تعریف تایپ آنها امکان پذیر است:
readonly class MyClass
{
public string $title;

// Error: 'readonly' property must have type specified
public $mixed;
}


3- از آنجایی که ویژگی های readonly نمی توانند static باشند، کلاس های readonly نمی توانند هیچ ویژگی static داشته باشند:
readonly class MyClass
{
// Error: Cannot declare 'static' properties in 'readonly' class
public static string $title;
}


4- ویژگی‌های یک کلاس readonly نمی‌توانند مقدار پیش‌فرض داشته باشند مگر اینکه از promoted properties استفاده کنید:
readonly class MyClass
{
// Error: 'readonly' property cannot have default value
public string $title = 'default';
}

// promoted properties:
readonly class MyClass
{
public function __construct(
public string $title = 'default', // This works
) {}
}


5- نمیتوان یک کلاس عادی را با readonly ادغام (extends) کرد مگر هر دو کلاس readonly باشند:
readonly class MyClass { /* … */ }

// Error: Non-'readonly' class cannot extend readonly class 'MyClass'
class OtherClass extends MyClass { /* … */ }


مثال:
فرض کنید یک کلاس برای مدیریت توکن ها دارید، و نمیخواید توکن ها تغییر کنند.
در این صورت میتوانید از readonly class استفاده کنید تا اطمینان داشته باشید در طول اجرای برنامه توکن تغییر نمیکند:
readonly class Token
{
public string $token;
public function __construct()
{
$this->token = 'ASDHAJKSHJDKHAJKSDHKAJSDJKADJKKJHDKJ';
}
}
echo (new Token())->token;


👤 AmirHossein

💎 Channel: @DevelopixPHP
8👍1
کلاس‌های ناشناس یا انانیموس در PHP، امکان تعریف کلاس‌هایی را می‌دهند که نام خاصی ندارند و بلافاصله پس از تعریف، نمونه‌سازی می‌شوند. این قابلیت اولین بار در PHP 7 معرفی شد و به توسعه‌دهندگان اجازه می‌دهد برای استفاده‌های یک‌باره یا محدود، سریع‌تر و منعطف‌تر کلاس تعریف کنند.

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

یک نمونه کلاس بی نام در زیر آماده هست:
$class = new class {

}

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

اغلب برای استفاده‌های یک‌باره یا در محدوده‌های محلی که نیازی به تعریف یک کلاس کامل نیست، به کار می‌روند.

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

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

interface Greeting {
public function sayHello();
}

// استفاده از کلاس ناشناس که اینترفیس Greeting را پیاده‌سازی می‌کند
$greeting = new class implements Greeting {
public function sayHello() {
return "Hello, Anonymous Class!";
}
};

echo $greeting->sayHello();

در این مثال، یک کلاس ناشناس که اینترفیس Greeting را پیاده‌سازی می‌کند، تعریف و بلافاصله نمونه‌سازی شده است. این اجازه می‌دهد برای موارد استفاده محدود یا تک‌باره، کدی تمیزتر و ساده‌تر نوشته شود.

در مثال دیگر میتوانیم یک کلاس ناشناس را به عنوان ورودی به یک تابع بدهیم:

my_function(new class {

});

عملکرد آنها دقیقا مشابه تابع های ناشناس (Anonymous function) یا (closure) می باشد.

اگر با Anonymous function ها آشنایی ندارید یا آشنایی کمی دارید در کامنت ها اطلاع دهید تا یک پست برای آنها نیز آماده کنیم.

👤 AmirHossein

💎 Channel: @DevelopixPHP
5
کلوژرها در PHP یکی از انواع مفید و قدرتمند توابع ناشناس هستند. کلوژرها به شما امکان می‌دهند توابعی بنویسید که می‌توانند متغیرهای خارجی از دامنه‌ی تعریف شده خود را "بگیرند" یا استفاده کنند، حتی اگر این متغیرها در دامنه‌ی global تعریف نشده باشند.

نحوه تعریف:
یک
کلوژر در PHP با استفاده از کلمه کلیدی function بدون نام فانکشن تعریف می‌شود. می‌توان آن را به یک متغیر اختصاص داد و مانند هر فانکشن دیگری، با فراخوانی نام متغیر می‌توان آن را اجرا کرد.

$my_function = function () {
// Code
};


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

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

آرگومان های ورودی‌ها و کلمه کلیدی use:
مانند
توابع عادی، کلوژرها می‌توانند پارامترهای ورودی داشته باشند. این پارامترها در زمان فراخوانی کلوژر به آن ارسال می‌شوند.
$my_function = function ($text) {
echo $text
};
$my_function('hello');
// hello


برای دسترسی به متغیرهای خارج از دامنه‌ی کلوژر، از کلمه کلیدی use استفاده می‌شود. این متغیرها در زمان تعریف کلوژر به آن "بسته" می‌شوند و مقادیر آنها حفظ می‌شود، حتی اگر بعداً تغییر کنند.
$text  = 'hello',
$my_function = function () use ($text) {
echo $text
};
$my_function();
// hello


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

$anotherNumber = 5;
$addition = function ($number) use ($anotherNumber) {
return $number + $anotherNumber;
};

echo $addition(3); // 8


کلوژ هارا میتوان به عنوان ورودی به متد ها یا توابع دیگر ارسال کرد:
function execute($action) {
$action();
}

execute(function () {
echo 'hello';
});

———
‏Arrow functions، یک قابلیت نوین و ساده‌تر برای نوشتن توابع ناشناس (Anonymous functions) هستند. این توابع به خصوص برای تعریف توابع کوچک و کاربردی طراحی شده‌اند که می‌توانند بلافاصله اجرا شوند.

نحوه تعریف:
‏Arrow
functions با استفاده از کلمه کلیدی fn به جای کلمه‌کلیدی function تعریف می‌شوند. ساختار کلی آنها به این شکل است:
$function = fn($arg1, $arg2, ...) => expression;


بدنه‌ی arrow function تنها شامل یک عبارت (expression) است و نیازی به استفاده از return برای برگرداندن نتیجه نیست. نتیجه‌ی این عبارت به طور خودکار برگردانده می‌شود.

تفاوت با فانکشن‌های عادی:
‏Arrow
functions بر خلاف توابع عادی، همیشه ناشناس هستند.
نتیجه به طور خودکار برگردانده می‌شود، بدون نیاز به استفاده از return.

تفاوت با کلوژرها:
‏Arrow functions به طور خودکار تمام متغیرهای مورد استفاده را از دامنه‌ی بیرونی "می‌گیرند"، بنابراین نیازی به استفاده از کلمه‌کلیدی use نیست.
کوتاه‌تر و مختصرتر از کلوژرها هستند و برای تعاریف تک خطی بهینه شده‌اند.

مثال :
فرض
کنید می‌خواهیم یک آرایه از اعداد را دو برابر کنیم. می‌توانیم از arrow function در تابع array_map استفاده کنیم:
$numbers = [1, 2, 3, 4];
$doubled = array_map(fn($number) => $number * 2, $numbers);

print_r($doubled);
//Array ( [0] => 2 [1] => 4 [2] => 6 [3] => 8 )


در این مثال، ما از یک arrow function به عنوان callback در array_map استفاده کردیم تا هر عنصر آرایه را دو برابر کنیم. این نمونه نشان دهنده‌ی سادگی و کارایی بالای arrow functions در PHP برای انجام عملیات‌های مختصر و مفید است. Arrow functions به ویژه هنگام کار با آرایه‌ها، کالکشن‌ها و دیتا استراکچرهایی که نیاز به ترانسفورمیشن دارند، مفید هستند.

👤 AmirHossein

💎 Channel: @DevelopixPHP
🔥42👍1
در‏ ‏PHP‏، parent, static, self‏, و $this کلیدواژه‌هایی هستند که برای دسترسی به ویژگی‌ها و متدهای مختلف کلاس‌ها استفاده می‌شوند. در اینجا توضیح و مثالی برای هر یک ارائه داده شده:

‏$this:
کلیدواژه $this به نمونه فعلی کلاس اشاره دارد. از این برای دسترسی به ویژگی‌ها و متدهای غیر استاتیک درون یک کلاس استفاده می‌شود.

مثال:
class Car {
public $color;

public function setColor($color) {
$this->color = $color;
}

public function getColor() {
return $this->color;
}
}

$car = new Car();
$car->setColor('blue');
echo $car->getColor(); // خروجی: blue

------
‏self:
کلیدواژه self به کلاسی اشاره دارد که در آن استفاده شده است. برای دسترسی به ویژگی‌ها و متدهای استاتیک کلاس مورد استفاده قرار می‌گیرد.

مثال:
class Car {
public static $number_of_cars = 0;

public function __construct() {
self::$number_of_cars++;
}

public static function getNumberOfCars() {
return self::$number_of_cars;
}
}

new Car();
new Car();
echo Car::getNumberOfCars(); // خروجی: 2

------

parent:
کلیدواژه parent برای دسترسی به ویژگی‌ها و متدهای کلاس والد استفاده می‌شود. معمولاً در زمینه‌هایی به کار می‌رود که وراثت مطرح است و می‌خواهیم به یک متد یا ویژگی در کلاس والد دسترسی داشته باشیم که در کلاس فرزند override شده است.

مثال:
class Vehicle {
protected function startEngine() {
echo "Engine started";
}
}

class Car extends Vehicle {
public function startEngine() {
parent::startEngine();
echo " and Car is ready!";
}
}

$car = new Car();
$car->startEngine(); // خروجی: Engine started and Car is ready!

------
‏static:
کلیدواژه static در جایی استفاده می‌شود که می‌خواهیم به ویژگی‌ها و متدهای استاتیک کلاس در حال اجرا دسترسی داشته باشیم، به ویژه در زمینه‌های وراثت که ممکن است نوع کلاس فرزند متفاوت باشد. static در زمان اجرا حل می‌شود و به کلاسی اشاره دارد که متد را فراخوانی کرده است.

مثال:
class Vehicle {
public static function who() {
echo "I am a Vehicle";
}

public static function test() {
static::who(); // دیر حل‌شدن: اینجا به "Vehicle" اشاره دارد
}
}

class Car extends Vehicle {
public static function who() {
echo "I am a Car";
}
}

Car::test(); // خروجی: I am a Car

در مثال بالا، با استفاده از static::who(), کلاس Car به جای Vehicle تشخیص داده شده است زیرا static به کلاسی اشاره دارد که متد در آن فراخوانی شده است. این مکانیزم به عنوان "Late Static Binding" شناخته می‌شود و به PHP اجازه می‌دهد که در زمان اجرا تصمیم بگیرد که کدام ورژن از متد باید استفاده شود، بر اساس کلاسی که متد را فراخوانی کرده، نه بر اساس کلاسی که متد در آن تعریف شده است.

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

برای درک بهتر static و self را در کنار هم میگذاریم:
class BaseClass {
public static function who() {
echo "I am a BaseClass";
}

public static function test() {
self::who(); // این همیشه به BaseClass اشاره دارد.
static::who(); // این می‌تواند به کلاس فرزند اشاره داشته باشد اگر override شده باشد.
}
}

class ChildClass extends BaseClass {
public static function who() {
echo "I am a ChildClass";
}
}

ChildClass::test();

خروجی این کد:
I am a BaseClass
I am a ChildClass

اولین خط با استفاده از self::who() همیشه به متد who() در BaseClass اشاره دارد، در حالی که دومین خط با استفاده از static::who() به متد who() در ChildClass اشاره دارد زیرا این متد در کلاس فرزند override شده است. این مثال نشان می‌دهد که چگونه self و static می‌توانند به طور متفاوتی عمل کنند و چرا static در موارد وراثت بسیار مفید است.

👤 AmirHossein

💎 Channel: @DevelopixPHP
👍94🔥2
کلون کردن (cloning) به روندی اشاره دارد که در آن یک نسخه دقیق از یک شیء موجود ایجاد می‌شود.
زمانی که یک شیء کلون می‌شود، یک شیء جدید با مقادیر خصوصیت‌های یکسان ایجاد می‌شود، اما این شیء جدید و اصلی در دو آدرس مموری مختلف قرار دارند، به این معنی که تغییرات بعدی در هر شیء تأثیری بر دیگری نخواهد داشت، مگر اینکه خصوصیات مرجع به اشتراک گذاشته شده باشند (مانند شیء‌هایی که از کلاس‌های دیگر، آرایه‌ها یا شیء‌های استاندارد تشکیل شده‌اند).

برای کلون کردن یک شیء در PHP، کلمه کلیدی clone استفاده می‌شود.
$object = new MyClass();
$cloned_object = clone $object;

کاربرد ها:
ایجاد نسخه‌های مستقل برای انجام عملیات‌هایی که نباید تأثیری بر نسخه اصلی داشته باشند.

جلوگیری از تغییرات ناخواسته در شیء اصلی زمانی که آن را به یک تابع می‌فرستید که ممکن است خصوصیات آن را تغییر دهد.

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

مثال کاربردی:
class Car {
public $model;
public $color;

public function __construct($model, $color) {
$this->model = $model;
$this->color = $color;
}
}

$originalCar = new Car('Ford', 'Red');
$clonedCar = clone $originalCar;
$clonedCar->color = 'Blue';

echo $originalCar->color; // خروجی: Red
echo $clonedCar->color; // خروجی: Blue

در این مثال، ما یک نمونه از کلاس Car ایجاد کردیم و آن را کلون کردیم. هر شیء حالا مستقل است و تغییر رنگ در $clonedCar تأثیری بر $originalCar ندارد.

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

کلون بصورت پیش‌فرض یک کپی سطحی است، ویژگی‌های پریمیتیو (مانند اعداد و رشته‌ها) به طور مستقل کپی می‌شوند، اما ویژگی‌هایی که به اشیاء یا آرایه‌های دیگر اشاره می‌کنند، به همان مراجع اصلی اشاره خواهند داشت.
کپی سطحی می‌تواند به مشکلاتی منجر شود اگر شما تغییراتی در یک شیء کلون شده ایجاد کنید که مراجع مشترک با شیء اصلی دارد؛ تغییرات می‌تواند بر شیء اصلی تأثیر بگذارد.
برای جلوگیری از این موضوع، ممکن است لازم باشد که یک کپی عمیق از شیء ایجاد کنید، به این معنی که هر شیء داخلی نیز به طور مستقل کپی می‌شود.در PHP، اگر می‌خواهید رفتار کلون کردن را کنترل کنید یا کپی عمیق را انجام دهید، می‌توانید از مجیک متد clone استفاده کنید. وقتی شما یک شیء را کلون می‌کنید، اگر مجیک متد clone در کلاس آن شیء تعریف شده باشد، به طور خودکار فراخوانی می‌شود. شما می‌توانید در این متد تعریف کنید که چه اتفاقی باید برای خصوصیات ارجاعی در هنگام کلون کردن بیفتد.

توضیحات و مثال های مربوط به مجیک متد __clone در پست های بعدی با مبحث مجیک متد ها داده میشود.

👤 AmirHossein

💎 Channel: @DevelopixPHP
👍5
مجیک متدها (Magic Methods) در PHP توابعی هستند که به طور خودکار در پاسخ به برخی رویدادهای خاص در شیء فراخوانی می‌شوند.
این توابع با دو علامت زیرخط (__) شروع می‌شوند. مجیک متدها به برنامه‌نویسان اجازه می‌دهند تا رفتارهای خاصی را در زمان اجرا، مانند ساختن یک شیء یا نابودی آن، اضافه، تغییر یا حذف خصوصیات و غیره، به کلاس‌های خود اضافه کنند.

در ادامه توضیحات کاملی برای هر یک از مجیک متد ها داده میشود.
اگرچه همه شما با مجیک متد های __construct و __destruct آشنا هستید ولی لازم است توضیحاتی برای آنها نیز داده شود.

متد __construct به عنوان سازنده کلاس عمل می‌کند و به محض ایجاد نمونه‌ای از کلاس فراخوانی می‌شود. این متد معمولاً برای اولیه‌سازی خصوصیات شیء و انجام تنظیمات اولیه استفاده می‌شود.

مثال:
class Person {
public $name;
public $age;

public function __construct($name, $age) {
$this->name = $name;
$this->age = $age;
}

public function greet() {
return "Hello, my name is " . $this->name . " and I am " . $this->age . " years old.";
}
}

$person = new Person("John", 30);
echo $person->greet();


متد __construct زمانی فراخوانی می‌شود که یک نمونه جدید از کلاس Person ساخته می‌شود. این متد دو پارامتر name و age را می‌گیرد و آن‌ها را به خصوصیات شیء اختصاص می‌دهد.
این روش برای اولیه‌سازی شیء با داده‌های اولیه استفاده می‌شود.
متد greet یک پیام خوش‌آمدگویی تولید می‌کند که نام و سن شخص را شامل می‌شود که در متد __construct مقدار دهی شده است.

———

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

مثال:
class FileHandler {
private $file;

public function __construct($filename) {
$this->file = fopen($filename, 'w');
}

public function write($data) {
fwrite($this->file, $data);
}

public function __destruct() {
fclose($this->file);
echo "File closed.\n";
}
}

$file = new FileHandler("example.txt");
$file->write("Hello World");
// Result: "File closed."


متد __construct برای باز کردن یک فایل جدید یا موجود استفاده می‌شود و فایل را در پراپرتی file ذخیره میکند.
متد write داده‌ای که به آن داده شده را در فایل می‌نویسد.
و در نهایت که شئ کاری برای انجام دادن ندارد و اسکریپت به پایان میرسد متد __destruct فراخوانی می‌شود و فایل باز شده را می بندد و پیام File closed. را چاپ میکند.

👤 AmirHossein

💎 Channel: @DevelopixPHP
👍9
مجیک متدهای __call و __callStatic در PHP برای دستکاری نحوه پاسخگویی کلاس‌ها به فراخوانی متدهایی که به صورت مستقیم تعریف نشده‌اند یا اصلا وجود ندارند، استفاده می‌شوند. این دو متد به شما اجازه می‌دهند تا رفتار انعطاف پذیرتری را در کلاس‌های خود ایجاد کنید.

مجیک متد __call:
زمانی فراخوانی می‌شود که به متدی غیر استاتیک در یک شیء دسترسی پیدا می‌کنید که وجود ندارد یا قابل دسترسی نیست.
این متد دو ورودی که به ترتیب نام متد فراخوانی شده و آرگومان های متد فراخوانی شده هستند را دریافت میکند.
ساختار آن به صورت زیر است:

public function __call($name, $arguments)
{

}


مثال:
class Person {
private $data = [
"name" => "John",
"age" => 30
];

public function __call($method, $params) {
if (array_key_exists($method, $this->data)) {
return $this->data[$method];
} else {
return "Method $method does not exist!";
}
}
}

$person = new Person();
echo $person->name(); // Outputs: John
echo $person->age(); // Outputs: 30
echo $person->height(); // Outputs: Method height does not exist!


در این مثال، کلاس Person دارای یک آرایه خصوصی $data است که حاوی اطلاعات است. وقتی که سعی می‌کنید به متدی دسترسی پیدا کنید که مستقیماً تعریف نشده‌است، متد __call فراخوانی می‌شود.
در این مثال همانطور که می بینید متد های name و age و height تعریف نشده اند ولی به واسطه متد __call مدیریت میشوند.
این متد چک می‌کند که آیا نام متد فراخوانی شده به عنوان کلید در آرایه $data وجود دارد یا خیر. اگر وجود داشته باشد، مقدار مربوطه را برمی‌گرداند و اگر نباشد، پیام خطا می‌دهد.

———

مجیک متد __callStatic:
مجیک متد __callStatic مشابه __call است، اما برای متدهای استاتیک که وجود ندارند یا قابل دسترسی نیستند فراخوانی می‌شود.

این متد نیز همانند __call دو ورودی که به ترتیب نام متد فراخوانی شده و آرگومان های متد فراخوانی شده هستند را دریافت میکند.
ساختار آن به صورت زیر است:
public static function __callStatic($name, $arguments)
{

}


مثال:
class Utility {
private static $data = [
"pi" => 3.14159,
"e" => 2.71828
];

public static function __callStatic($method, $params) {
if (array_key_exists($method, self::$data)) {
return self::$data[$method];
} else {
return "Static method $method does not exist!";
}
}
}

echo Utility::pi(); // Outputs: 3.14159
echo Utility::e(); // Outputs: 2.71828
echo Utility::golden(); // Outputs: Static method golden does not exist!


در این مثال، کلاس Utility دارای یک آرایه خصوصی استاتیک $data است. وقتی به متد استاتیکی که تعریف نشده دسترسی پیدا می‌کنید، __callStatic فعال می‌شود. این متد بررسی می‌کند که آیا نام متد به عنوان کلید در $data وجود دارد. اگر بله، مقدار مربوطه را برمی‌گرداند و اگر نه، پیام خطا می‌دهد.


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

👤 AmirHossein

💎 Channel: @DevelopixPHP
6👍3🔥1
در PHP، مجیک متد‌های __get و __set برای دسترسی به پراپرتی که به طور مستقیم قابل دسترسی نیستند یا وجود خارجی ندارند، استفاده می‌شوند. این مجیک متدها اجازه می‌دهند تا شما در هنگام دسترسی یا تنظیم مقادیر پراپرتی کلاس، کنترل بیشتری داشته باشید. به عبارت دیگر، وقتی خواسته می‌شود که به یک پراپرتی دسترسی پیدا شود که تعریف نشده است یا دسترسی مستقیم به آن امکان‌پذیر نیست، این متد‌ها فعال می‌شوند.

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

مثال:
class User {
private $data = [
"name" => "John Doe",
"email" => "john@example.com"
];

public function __get($name) {
if (array_key_exists($name, $this->data)) {
return $this->data[$name];
} else {
return null;
}
}
}

$user = new User();
echo $user->name; // Outputs: John Doe
echo $user->email; // Outputs: john@example.com
echo $user->age; // Outputs: null


در این مثال، هرگاه که می‌خواهیم به name یا email دسترسی پیدا کنیم، مجیک متد __get فراخوانی شده و مقدار مربوطه برگردانده می‌شود. اگر پراپرتی وجود نداشته باشد، null برگردانده می‌شود.

مجیک متد __set:
این مجیک متد زمانی فراخوانی می‌شود که سعی می‌کنید مقدار یک پراپرتی که وجود ندارد یا خصوصی است را تنظیم کنید.

مثال:
class User {
private $data = [
"name" => "John Doe",
"email" => "john@example.com"
];

public function __set($name, $value) {
if (array_key_exists($name, $this->data)) {
$this->data[$name] = $value;
}
}
}

$user = new User();
$user->name = "Jane Doe"; // changes the name property
echo $user->name; // Outputs: Jane Doe


در این مثال، مقدار name از طریق مجیک متد __set تغییر می‌کند. اگر پراپرتی وجود نداشته باشد، امکان افزودن یا تغییر آن وجود ندارد و می‌توانید خطایی را لاگ یا اکسپشن بیندازید.

مثال تکمیلی:
class Product {
private $data = [];

public function __set($key, $value) {
switch ($key) {
case "price":
if (!is_numeric($value) || $value < 0) {
throw new Exception("Invalid price");
}
break;
case "name":
$value = trim(strip_tags($value));
break;
}
$this->data[$key] = $value;
}

public function __get($key) {
return $this->data[$key] ?? null;
}
}

$product = new Product();
$product->name = "New <b>Product</b>"; // HTML tags will be removed
$product->price = 20;

echo $product->name; // Outputs: New Product
echo $product->price; // Outputs: 20


در این مثال، مجیک متد __set به گونه‌ای تعریف شده است که قبل از ذخیره‌سازی، مقدار قیمت را بررسی می‌کند تا از صحت آن اطمینان حاصل کند و از ذخیره‌سازی مقادیر نامعتبر جلوگیری کند. همچنین، نام محصول از تگ‌های HTML پاک می‌شود.
سپس توسط مجیک متد __get نام و قیمت دریافت می شود.
همه این ها در حالی است که پراپرتی های name و price در کلاس ما وجود ندارند.

مجیک متدهای __get و __set در PHP ابزارهای قدرتمندی هستند که به شما امکان می‌دهند کنترل بیشتری بر نحوه دسترسی و تغییر داده‌ها در کلاس‌هایتان داشته باشید.

👤 AmirHossein

💎 Channel: @DevelopixPHP
👍51🔥1
مجیک متد های __isset و __unset برای کنترل دسترسی به ویژگی‌هایی که نامعلوم یا ناقابل دسترس هستند.

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


مثال:
تصور
کنید یک کلاس با ویژگی‌های خصوصی داریم و می‌خواهیم بررسی کنیم که آیا یک ویژگی خصوصی تنظیم شده است یا خیر:
class User {
private $data = [
'name' => 'John Doe',
'email' => 'john@example.com'
];

public function __isset($property) {
return isset($this->data[$property]);
}
}

$user = new User();
echo isset($user->name) ? 'Name is set' : 'Name is not set';
// Output: Name is set


در این مثال بررسی میشود که پراپرتی name در کلاس User موجود است یا خیر، این درحالی است که این پراپرتی به طور مستقیم در دسترس نیست.

مجیک متد __unset:
مجیک متد __unset زمانی فعال می‌شود که تابع unset() بر روی ویژگی‌هایی که به طور مستقیم دسترسی‌پذیر نیستند، فراخوانی شود. این به شما اجازه می‌دهد که تعریف کنید چه اتفاقی باید هنگام حذف یک ویژگی رخ دهد.
این مجیک متد یک ورودی میگیرد که نام پراپرتی unset شده میباشد.

مثال:
class User {
private $data = [
'name' => 'John Doe',
'email' => 'john@example.com'
];

public function __unset($property) {
echo "Unsetting property '$property'\n";
unset($this->data[$property]);
}
}

$user = new User();
unset($user->name);


در این مثال، وقتی unset($user->name) فراخوانی می‌شود، مجیک متد __unset اجرا می‌شود و پیامی مبنی بر حذف ویژگی نمایش داده می‌شود و ویژگی مورد نظر را از آرایه داده‌های داخلی کلاس حذف می‌کند.
این نیز درحالی است که پراپرتی name مستقیما در کلاسی User موجود نمیباشد.


این دو مجیک متد، __isset و __unset، ابزارهای مفیدی در PHP هستند که به شما اجازه می‌دهند تا رفتار دسترسی به ویژگی‌ها و حذف آن‌ها در کلاس‌های شما را به شکل کنترل‌شده‌ای مدیریت کنید. استفاده از این مجیک متدها به خصوص در مواقعی که با داده‌های حساس یا پیچیده کار می‌کنید، می‌تواند بسیار مفید باشد. این تکنیک‌ها به شما اجازه می‌دهند تا یک واسط کاربری برنامه‌نویسی روان‌تر و ایمن‌تری را ارائه دهید، زیرا می‌توانید جلوی دسترسی مستقیم به ویژگی‌های داخلی کلاس را بگیرید و در عین حال به کاربران اجازه دهید تا تنها عملیات‌های معتبر را روی آن‌ها انجام دهند.

👤 AmirHossein

💎 Channel: @DevelopixPHP
🔥5👍2
مجیک متدهای __sleep و __wakeup در PHP به شما امکان می‌دهند کنترلی بر فرآیند سریالیزه کردن و دسریالیزه کردن یک شیء را داشته باشید.

مجیک متد __sleep :
وقتی یک شیء در PHP سریالیزه می‌شود (برای ذخیره شدن آن در فایل یا ارسال آن از طریق شبکه)، مجیک متد __sleep فراخوانی می‌شود. این مجیک متد امکان می‌دهد تا شما مشخص کنید که کدام ویژگی‌های شیء باید قبل از سریالیزه شدن ذخیره شوند.

مثال:
class MyClass {
public $name;
public $age;
public $city;

public function __construct($name, $age, $city) {
$this->name = $name;
$this->age = $age;
$this->city = $city;
}

public function __sleep() {
return array('name', 'age');
}
}

$obj = new MyClass('John', 30, 'New York');
$data = serialize($obj);
echo $data;
// Output: O:7:"MyClass":2:{s:4:"name";s:4:"John";s:3:"age";i:30;}


در این مثال، ما یک کلاس به نام MyClass داریم که سه ویژگی name، age و city را دارد. ما یک مجیک متد __construct داریم که مقادیر این ویژگی‌ها را تنظیم می‌کند.
سپس، ما مجیک متد __sleep را به کلاس اضافه می‌کنیم. این مجیک متد در زمانی که یک شیء از این کلاس سریالیزه می‌شود، فراخوانی می‌شود و آرایه‌ای از نام‌های ویژگی‌ها را که قبل از سریالیزه شدن باید ذخیره شوند، برمی‌گرداند.
در نهایت، ما یک شیء از این کلاس ایجاد می‌کنیم و آن را سریالیزه می‌کنیم.
وقتی این برنامه اجرا می‌شود، فقط ویژگی‌های name و age از شیء $obj در زمان سریالیزه شدن ذخیره می‌شوند.

———

مجیک متد __wakeup:
وقتی یک شیء سریالیزه شده را می‌خوانید و به شیء تبدیل می‌کنید، مجیک متد __wakeup فراخوانی می‌شود. این مجیک متد به شما اجازه می‌دهد که فرآیند بازیابی داده‌ها پس از دسریالیزه کردن را کنترل کنید.

مثال:
class MyClass {
public $name;
public $age;
public $city;

public function __construct($name, $age, $city) {
$this->name = $name;
$this->age = $age;
$this->city = $city;
}

public function __sleep() {
return array('name', 'age');
}

public function __wakeup() {
$this->city = 'Unknown';
}
}

$data = 'O:7:"MyClass":2:{s:4:"name";s:4:"John";s:3:"age";i:30;}';
$obj = unserialize($data);
var_dump($obj);

/*
Output:

object(MyClass)#1 (3) {
["name"]=>
string(4) "John"
["age"]=>
int(30)
["city"]=>
string(7) "Unknown"
}
*/


در این مثال، ما از همان کلاس MyClass استفاده می‌کنیم. اما در اینجا ما مجیک متد __wakeup را به کلاس اضافه می‌کنیم. این مجیک متد هنگامی که یک شیء از این کلاس دسریالیزه می‌شود، فراخوانی می‌شود و این امکان را به ما می‌دهد که داده‌هایی را پس از دسریالیزه کردن تغییر دهیم.
سپس، ما یک رشته حاوی داده سریالیزه شده را به کلاس MyClass منتقل می‌کنیم و آن را با استفاده از تابع unserialize دسریالیزه می‌کنیم.
وقتی این برنامه اجرا می‌شود، وقتی که $obj دسریالیزه می‌شود، مجیک متد __wakeup فراخوانی می‌شود و مقدار city به "Unknown" تنظیم می‌شود.

به طور خلاصه، مجیک متدهای __sleep و __wakeup در PHP ابزارهایی هستند که به شما امکان می‌دهند کنترلی دقیق بر فرآیند سریالیزه کردن و دسریالیزه کردن یک شیء داشته باشید.

👤 AmirHossein

💎 Channel: @DevelopixPHP
👍7🔥3
مجیک متدهای __serialize و __unserialize در PHP بخشی از ویژگی‌های مدیریت سریالیزیشن اشیاء هستند. این متدها به شما امکان می‌دهند که کنترل دقیق‌تری بر روند سریالیزیشن و آنسریالیزیشن اشیاء داشته باشید. این کاربرد به ویژه در مواقعی مفید است که شیء شامل داده‌هایی است که نیاز به سریالیزیشن خاصی دارند یا باید از سریالیزیشن برخی داده‌ها جلوگیری شود.

مجیک متد __serialize:
این متد به شما امکان می‌دهد که تعیین کنید کدام داده‌های یک شیء هنگام سریالیزیشن ذخیره شوند. این کار از طریق برگرداندن یک آرایه که شامل نام‌ها و مقادیر متغیرهایی که باید سریالیز شوند، انجام می‌پذیرد.

مثال:
فرض کنید می‌خواهیم کلاس User را داشته باشیم که می‌خواهیم هنگام سریالیزیشن، رمز عبور را حذف کنیم تا در داده‌های سریال شده ذخیره نشود.

class User {
public $username;
private $password;
public $email;

public function __construct($username, $password, $email) {
$this->username = $username;
$this->password = $password;
$this->email = $email;
}

public function __serialize(): array {
return [
'username' => $this->username,
'email' => $this->email
];
}
}

$user = new User('alice', 'secretPassword123', 'alice@example.com');
$serializedUser = serialize($user);

در این مثال، وقتی شیء $user سریالیز می‌شود، متد __serialize فقط username و email را برمی‌گرداند و password سریالیز نمی‌شود.

———

مجیک متد __unserialize:
این متد هنگام آنسریالیزیشن یک شیء فراخوانی می‌شود و به شما امکان می‌دهد که مشخص کنید چگونه داده‌های آنسریالیز شده باید در شیء بازیابی شوند. این متد یک آرایه از داده‌ها را به عنوان ورودی می‌گیرد و شما می‌توانید این داده‌ها را در ویژگی‌های شیء تنظیم کنید.

مثال:
حالا
، برای همان کلاس User، متد __unserialize را پیاده‌سازی می‌کنیم تا هنگام آنسریالیزیشن، رمز عبور را به یک مقدار پیش‌فرض تنظیم کنیم.

class User {
public $username;
private $password;
public $email;

public function __construct($username, $password, $email) {
$this->username = $username;
$this->password = $password;
$this->email = $email;
}

public function __unserialize(array $data): void {
$this->username = $data['username'];
$this->email = $data['email'];

$this->password = 'defaultPassword';
}
}

$serializedUser = 'O:4:"User":2:{s:8:"username";s:5:"alice";s:5:"email";s:17:"alice@example.com";}';
$user = unserialize($serializedUser);

در این مثال، هنگام آنسریالیزیشن، username و email از داده‌های سریال شده بازیابی می‌شوند و password به 'defaultPassword' تنظیم می‌شود. این روش مطمئن می‌کند که هیچ داده حساسی از طریق فرآیند سریالیزیشن و آنسریالیزیشن افشا نشود.

———
تفاوت ها با مجیک متد های __sleep و __wakeup:

__sleep:
مجیک متد __sleep قبل از سریالیزیشن یک شیء فراخوانی می‌شود. هدف از این متد آماده‌سازی شیء برای سریالیزیشن است. __sleep باید یک آرایه از نام‌های خصوصیاتی که قرار است سریالیز شوند را برگرداند. خصوصیاتی که در این آرایه ذکر نشده‌اند در نتیجه سریالیزیشن حذف می‌شوند و حالت فعلی آن‌ها از بین می‌رود.
———

__wakeup:
پس از آنکه شیء آنسریالیز شد، متد __wakeup فراخوانی می‌شود. این متد برای بازیابی منابع یا انجام تنظیمات خاص پس از آنسریالیزیشن استفاده می‌شود، مثلاً بازکردن اتصالات پایگاه داده یا دیگر منابعی که نمی‌توانند مستقیماً سریالیز شوند.
———

__serialize:
این متد جدیدتر و انعطاف‌پذیرتر است و به شما اجازه می‌دهد که دقیقاً مشخص کنید چه داده‌هایی باید به چه شکلی سریالیز شوند. با __serialize، می‌توانید یک آرایه کلید-مقدار برگردانید که دقیقاً نشان‌دهنده‌ی آن چیزی است که می‌خواهید سریالیز شود. این روش فرصت‌های بیشتری برای مدیریت حالت شیء فراهم می‌کند.
———

__unserialize:
هنگام آنسریالیزیشن، __unserialize فراخوانی می‌شود و یک آرایه از داده‌ها را دریافت می‌کند. این متد به شما اجازه می‌دهد که مشخص کنید چگونه این داده‌ها باید در شیء استفاده شوند و به شما امکان می‌دهد تنظیمات لازم را اعمال کنید.
———

مجیک متدهای __serialize و __unserialize به شما کنترل دقیق‌تری بر داده‌هایی که سریالیز و آنسریالیز می‌شوند می‌دهند، در حالی که __sleep و __wakeup بیشتر برای مدیریت ویژگی‌ها و منابع استفاده می‌شوند.

👤 AmirHossein

💎 Channel: @DevelopixPHP
5👍1
مجیک متد __toString در PHP برای تعریف نحوه تبدیل یک شیء به رشته استفاده می‌شود. این مجیک متد زمانی فراخوانی می‌شود که شیء به صورت خودکار باید به یک رشته تبدیل شود، مثلاً زمانی که می‌خواهیم یک شیء را به عنوان یک رشته چاپ کنیم یا در یک رشته ادغام کنیم. این قابلیت برای ارائه نمایش معنادار و قابل فهم از شیء در قالب رشته بسیار مفید است.

مجیک متد __toString هیچ پارامتری ندارد و یک رشته برگرداند.

مثال:
فرض کنید می‌خواهیم یک کلاس برای نمایش اطلاعات کتاب در یک کتابخانه داشته باشیم. ما می‌توانیم مجیک متد __toString را به کار ببریم تا یک خلاصه مناسب از کتاب را زمانی که نیاز به نمایش آن به صورت رشته‌ای داریم، تولید کنیم.
class Book {
private $title;
private $author;
private $year;

public function __construct($title, $author, $year) {
$this->title = $title;
$this->author = $author;
$this->year = $year;
}

public function __toString() {
return "{$this->title} written by {$this->author}, published in {$this->year}.";
}
}

$book = new Book("The Little Prince", "Antoine de Saint-Exupéry", 1945);
echo $book;
// Output: The Little Prince written by Antoine de Saint-Exupéry , published in 1945


در این مثال، کلاس Book شامل سه خصوصیت (عنوان، نویسنده، و سال نشر) است. مجیک متد __construct برای تعیین این خصوصیات هنگام ایجاد شیء استفاده می‌شود، و مجیک متد __toString برای تولید یک رشته خلاصه از کتاب به کار می‌رود. زمانی که echo برای نمایش شیء استفاده می‌شود، مجیک متد __toString به طور خودکار فراخوانی می‌شود و رشته مورد نظر چاپ می‌گردد.

———

مجیک متد __debugInfo در PHP به شما اجازه می‌دهد تعیین کنید چه اطلاعاتی باید زمان استفاده از تابع var_dump برای شیء نمایش داده شود. این مجیک متد به خصوص در مواقعی مفید است که شما می‌خواهید برخی از جزئیات داخلی شیء را مخفی کنید یا فرمت خروجی را سفارشی سازی کنید.

مجیک متد __debugInfo باید یک آرایه را برگرداند که کلیدهای آن نشان دهنده نام‌های خصوصیاتی هستند که باید در خروجی var_dump نمایش داده شوند، و مقادیر آن خود داده‌هایی هستند که باید نمایش داده شوند.

مثال:
فرض کنید می‌خواهیم کلاس User داشته باشیم که شامل اطلاعات حساس مثل رمز عبور است. ما می‌خواهیم که زمان استفاده از var_dump بر روی نمونه‌های این کلاس، رمز عبور نمایش داده نشود.
<?php

class User {
private $username;
private $password;
private $email;

public function __construct($username, $password, $email) {
$this->username = $username;
$this->password = $password;
$this->email = $email;
}

public function __debugInfo() {
return [
'username' => $this->username,
'email' => $this->email
];
}
}


$user = new User("ali", "12345", "ali@example.com");
var_dump($user);
/*
Output:
object(User)#1 (2) {
["username"]=>
string(3) "ali"
["email"]=>
string(15) "ali@example.com"
}
*/


در این مثال، کلاس User شامل سه خصوصیت است: نام کاربری، رمز عبور و ایمیل. مجیک متد __construct برای مقداردهی این خصوصیات استفاده می‌شود. مجیک متد __debugInfo تعریف شده است تا زمانی که var_dump بر روی نمونه‌های این کلاس اجرا می‌شود، رمز عبور نمایش داده نشود. به جای آن، فقط نام کاربری و ایمیل نمایش داده می‌شوند. این روش کنترل بیشتری بر داده‌هایی که ما می‌خواهیم نمایش داده شود و نشود به ما می‌دهد، و از نمایش اطلاعات حساس در محیط‌های توسعه جلوگیری می‌کند.

👤 AmirHossein

💎 Channel: @DevelopixPHP
🔥4👍1
مجیک متد __invoke در PHP به شیء اجازه می‌دهد تا همچون یک تابع عمل کند. یعنی وقتی شی‌ای از کلاسی که این مجیک متد در آن تعریف شده است، ساخته می‌شود، می‌تواند مستقیماً فراخوانی شود.

مثال:
فرض کنید می‌خواهیم یک کلاس داشته باشیم که عملیات ریاضی را انجام دهد. می‌توانیم __invoke را استفاده کنیم تا بتوانیم شیء را مانند یک تابع فراخوانی کنیم و یک عملیات را انجام دهیم.

class MathOperation {
private $operand;

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

public function __invoke($number) {
return $number * $this->operand;
}
}

$double = new MathOperation(2);
echo $double(10); // Output: 20


در این مثال، شیء $double همچون یک تابع فراخوانی شده و عدد 10 را دو برابر می‌کند.

———

مجیک متد __set_state در زمانی که می‌خواهیم نمایش خروجی یک شیء را با استفاده از تابع var_export کنترل کنیم، به کار می‌رود. این مجیک متد باید به صورت استاتیک تعریف شود و برای بازسازی نمونه‌های کلاس‌ها استفاده می‌شود. وقتی var_export بر روی یک شیء فراخوانی می‌شود و کلاس آن شیء دارای مجیک متد __set_state است، خروجی که تولید می‌شود قابل استفاده برای بازسازی شیء خواهد بود.

مجیک متد __set_state یک آرایه از متغیرها را دریافت کند و باید یک شیء از کلاس را برگرداند. این آرایه معمولاً شامل تمامی ویژگی‌های شیء است که با دسترسی‌های مختلف تعریف شده‌اند.

مثال:
در این مثال، ما یک کلاس ساده به نام Person را تعریف می‌کنیم که دارای دو ویژگی name و age است و مجیک متد __set_state را برای آن تعریف می‌کنیم:

class Person {
public $name;
public $age;

public static function __set_state($an_array) {
$obj = new Person;
$obj->name = $an_array['name'];
$obj->age = $an_array['age'];
return $obj;
}
}

$person = new Person;
$person->name = 'John';
$person->age = 30;

$exported = var_export($person, true);

eval('$restored_person = ' . $exported . ';');
echo $restored_person->name; // Output: John
echo $restored_person->age; // Output: 30


مجیک متد __set_state برای بازسازی شیء از آرایه‌ای که توسط var_export تولید شده استفاده می‌کند.
تابع var_export برای تولید یک رشته است که نمایش دهنده کد PHP برای بازسازی شیء Person است.
با استفاده از eval شیء جدیدی از رشته خروجی var_export ساخته می‌شود و می‌توان مقادیر ویژگی‌های آن را استخراج کرد.

👤 AmirHossein

💎 Channel: @DevelopixPHP
5👍2
مجیک متد __clone زمانی فراخوانی می‌شود که یک شیء کلون شود. استفاده از کلون به شما اجازه می‌دهد یک نسخه دقیق از یک شیء موجود را ایجاد کنید، اما با این توانایی که رفتار پیش‌فرض کلون را اصلاح کنید. این بدان معناست که می‌توانید تنظیمات ویژه‌ای را برای نحوه کپی شدن خصوصیات شیء اعمال کنید، بخصوص زمانی که با خصوصیاتی که به شیء‌های دیگر اشاره دارند سروکار دارید.

مثال:
فرض
کنید که شما یک کلاس برای مدیریت پروفایل کاربر دارید و می‌خواهید که هر کلون از این کلاس دارای تنظیمات پیش‌فرض مشابهی باشد اما بتوان آن را به صورت جداگانه تنظیم کرد:
class UserProfile {
public $name;
public $email;
private $settings;

public function __construct($name, $email)
{
$this->name = $name;
$this->email = $email;
$this->settings = new stdClass();
$this->settings->theme = "default";
}

public function __clone()
{
$this->settings = clone $this->settings;
}
}

$user1 = new UserProfile("Ali", "ali@example.com");
$user2 = clone $user1;
$user2->name = "Reza";
$user2->settings->theme = "dark";

echo $user1->name . " has theme " . $user1->settings->theme . "\n";
// Ali has theme default
echo $user2->name . " has theme " . $user2->settings->theme . "\n";
// Reza has theme dark


در مثال ارائه شده، یک کلاس به نام UserProfile تعریف شده که حاوی اطلاعات کاربر است. وقتی شیء این کلاس کلون می‌شود، مجیک متد __clone فعال شده و به جای اینکه تنها به شیء settings ارجاع دهد، یک نسخه کاملاً جدید از آن را ایجاد می‌کند.
این کار موجب می‌شود که هر کاربر کلون شده دارای تنظیمات مستقل خود باشد و تغییرات اعمال شده بر روی یک شیء، بر شیء دیگر تأثیر نگذارد. این امکان از طریق کپی عمیق انجام می‌شود که به معنای کپی کردن همه خصوصیات، و نه فقط ارجاع‌ها، به نسخه کلون شده است.

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

کپی سطحی (Shallow Copy):
در این نوع کپی، فقط خصوصیات سطحی شیء کپی می‌شوند و هر خصوصیتی که به شیء دیگری ارجاع دهد، فقط ارجاع کپی می‌شود. این بدین معنی است که شی‌های اصلی و کلون شده به همان شیء ارجاعی اشاره خواهند کرد.

کپی عمیق (Deep Copy):
کپی عمیق شامل کپی کردن شیء و همچنین هر شیء دیگری است که توسط خصوصیات اصلی به آن اشاره شده است. این اطمینان حاصل می‌کند که شیء کلون شده و شیء اصلی هیچ ارتباط مستقیمی با یکدیگر ندارند. استفاده از مجیک متد __clone در PHP این امکان را می‌دهد که شما بتوانید کپی عمیق را اجرا کنید و خصوصیاتی که به شیء‌های دیگر اشاره دارند را نیز به صورت مجزا کپی کنید.

👤 AmirHossein

💎 Channel: @DevelopixPHP
🔥4👍2
مجیک کانستنت‌ها در PHP مقادیر ثابتی هستند که بسته به نحوه استفاده آن‌ها در کد، مقادیرشان تغییر می‌کنند. این کانستنت‌ها اغلب برای ارائه اطلاعات در مورد کد، مانند محل فایل‌ها یا نام کلاس‌ها، استفاده می‌شوند.

__LINE__:

شماره خط فعلی در فایل اسکریپت که در آن قرار دارد را برمی‌گرداند. این برای دیباگ کردن مفید است تا بفهمید خطا در کدام قسمت رخ داده است.

<?php
echo "This is line " . __LINE__;


Output: This is line 2

———

__FILE__:

مسیر کامل فایل جاری را برمی‌گرداند. این کانستنت می‌تواند برای تعیین مکان فایل‌ها هنگام ایجاد مسیرهای داینامیک یا لود کردن فایل‌ها به کار رود.

<?php
echo "This file is " . __FILE__;


Output: This file is C:\Users\{SysName}\Desktop\index.php

———

__DIR__:

مسیر دایرکتوری فایل جاری را برمی‌گرداند. این برای دسترسی به دیگر فایل‌ها یا دایرکتوری‌ها که نسبت به فایل جاری قرار دارند، مفید است.

<?php
echo "Directory path is " . __FILE__;


Output: Directory path is C:\Users\{SysName}\Desktop

———

__FUNCTION__:

نام تابع جاری را برمی‌گرداند. اگر داخل یک تابع نباشید، این کانستنت مقداری خالی برمی‌گرداند. در صورت داشتن Namespace نام تابع همراه با Namespace برگردانده می شود.

function test() {
echo "Function name is " . __FUNCTION__;
}
test();


Output: Function name is test


———

__CLASS__:

نام کلاس جاری را برمی‌گرداند. در صورتی که خارج از یک کلاس باشید، این کانستنت مقداری خالی برمی‌گرداند. در صورت داشتن Namespace نام کلاس همراه با Namespace برگردانده می شود.

class Sample {
public function getClassName() {
echo "Class name is " . __CLASS__;
}
}
$obj = new Sample();
$obj->getClassName();


Output: Class name is Sample

———

__TRAIT__:

نام trait جاری را برمی‌گرداند.در صورتی که خارج از یک Trait باشید، این کانستنت مقداری خالی برمی‌گرداند. در صورت داشتن Namespace نام تریت همراه با Namespace برگردانده می شود.

trait Sample
{
public function getTraitName() {
echo "Trait name is " . __TRAIT__;
}
}

class Test
{
use Sample;
}

$obj = new Test();
$obj->getTraitName();


Output: Trait name is Sample


———

__METHOD__:

نام متد جاری را به همراه نام کلاس برمی‌گرداند. این برای تشخیص دقیق‌تر متدی که در آن قرار دارید مفید است. در صورت داشتن Namespace نام متد همراه با Namespace برگردانده می شود.

class Sample {
public function getMethodName() {
echo "Method name is " . __METHOD__;
}
}
$obj = new Sample();
$obj->getMethodName();


Output: Method name is Sample::getMethodName


———

__NAMESPACE__:

نام فضای نام (namespace) جاری را برمی‌گرداند. این برای مدیریت کد در پروژه‌های بزرگ که از نیم‌اسپیس‌ها برای جداسازی کد استفاده می‌کنند، مفید است.

namespace Test\MyNamespace;
echo "Namespace name is " . __NAMESPACE__;


Output: Namespace name is Test\MyNamespace


———

ClassName::class:

نام کامل کلاس را برمیگرداند. در صورت داشتن Namespace نام کلاس همراه با Namespace برگردانده می شود.

<?php
class Sample { }
echo Sample::class;


Output: Sample


👤 AmirHossein

💎 Channel: @DevelopixPHP
👍95🔥3
کلمه کلیدی yield در PHP برای ساخت جنراتورها استفاده می‌شود. جنراتورها امکان ایجاد سری‌هایی از داده‌ها را فراهم می‌کنند بدون اینکه نیاز به بارگذاری همه آن‌ها در حافظه باشد. این ویژگی خصوصاً برای کار با داده‌های حجیم یا عملیات‌هایی که به تولید تعداد زیادی داده نیاز دارند مفید است.

‏yield در واقع مقداری را به Caller (تابعی که جنراتور را فراخوانی می‌کند) بازمی‌گرداند، اما در عین حال حالت فعلی جنراتور را نیز ذخیره می‌کند تا بتوان بعداً از همان نقطه ادامه داد. این تفاوت اصلی بین yield و return است؛ return کارکرد تابع را به طور کامل پایان می‌دهد، در حالی که yield این امکان را می‌دهد که تابع بعداً از همان نقطه توقف اجرا شود.

مثال :
فرض کنید که ما یک فایل بزرگ لاگ داریم که می‌خواهیم هر خط آن را بخوانیم و بررسی کنیم. به جای خواندن کامل فایل در حافظه، می‌توانیم از جنراتور برای خواندن خط به خط استفاده کنیم تا مصرف حافظه را کاهش دهیم.

function readLargeFile($filename) {
$handle = fopen($filename, "r");

while (!feof($handle)) {
yield fgets($handle);
}

fclose($handle);
}

foreach (readLargeFile("large_log_file.txt") as $line) {
echo $line . "<br>";
}


در این مثال، تابع readLargeFile به عنوان یک جنراتور عمل می‌کند. این تابع ابتدا فایل مورد نظر را برای خواندن باز می‌کند. درون حلقه while، از fgets برای خواندن هر خط از فایل استفاده می‌کنیم. تابع fgets خط بعدی را از فایل می‌خواند، و با استفاده از yield، این خط را به کد خارج از تابع برمی‌گرداند.

با استفاده از حلقه foreach، ما می‌توانیم هر خطی که جنراتور readLargeFile باز می‌گرداند را استفاده کنیم. این اجازه می‌دهد که هر خط را بلافاصله پردازش کنیم بدون اینکه نیاز باشد کل فایل در حافظه بارگذاری شود. این روش بسیار مؤثری برای کار با فایل‌های بزرگ است، زیرا فقط بخشی از فایل که در حال پردازش است در حافظه نگه داشته می‌شود، و بنابراین مصرف حافظه به شدت کاهش می‌یابد.

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

👤 AmirHossein

💎 Channel: @DevelopixPHP
👍64🔥2
در ‏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