معرفی

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

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

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

توابع تعریف شده توسط کاربر

نوشتن کد یکسان در چندین مکان، خواندن و درک یک پروژه را دشوار می کند. یکی از “اصول اصلی” یا اصول اساسی برنامه نویسی “خودت را تکرار نکن” است که اغلب به آن برنامه نویسی DRY می گویند. متغیرها ما را از نوشتن مکرر داده های مشابه باز می دارند. توابع ما را از نوشتن مکرر یک عمل باز می دارند.

ایجاد و فراخوانی توابع

هنگام نوشتن یک تابع، ابتدا ساختار تابع باید ساخته شود. این بلوک کد تا زمانی که فراخوانی یا فراخوانی نشود غیرفعال می ماند. یک تابع با استفاده از کلمه کلیدی تابع به اضافه یک نام انتخاب شده به دنبال پرانتز ایجاد می شود. بدنه تابع توسط پرانتزهای مجعد احاطه شده است و کدی است که عمل را انجام می دهد:

hello.php
<?php
function hello() {
    echo "Hello World!";
}

این تابع که hello نام دارد، غیر فعال می ماند، یعنی هیچ کاری انجام نمی دهد و تا زمانی که تابع فراخوانی نشود، فایل خروجی نخواهد داشت. برای فراخوانی یک تابع، از نام و به دنبال آن پرانتز استفاده می شود:

hello.php
<?php
function hello() {
    echo "Hello World!";
}
hello();

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

Output
Hello World!

این مثال ساده استفاده خوبی از یک تابع نیست، زیرا هیچ ورودی وجود ندارد، به این معنی که هیچ رابطه ای وجود ندارد و فقط خروجی وجود دارد. داده های مورد استفاده در مکان های مختلف باید در یک متغیر ذخیره شوند، مانند این:

hello.php
<?php
$hello = "Hello World!";
echo $hello;

این دو خط نتیجه مشابه تابع و فراخوانی را ارائه می دهند:

Output
Hello World!

اجازه دهید تابع مثال را برای پذیرش ورودی گسترش دهیم.

آرگومان ها و پارامترها

برای ایجاد یک تابع hello که رابطه ای بین ورودی و خروجی ایجاد می کند، تابع باید مقداری ورودی را بپذیرد. این ورودی به عنوان یک متغیر بین پرانتزهای تعریف تابع پذیرفته می شود. سپس این متغیر را می توان در بدنه تابع استفاده کرد:

hello.php
<?php
function hello($name) {
    echo "Hello ".$name;
}
hello();

تابع hello اکنون یک پارامتر ذخیره شده در متغیر $name را می پذیرد. سپس این متغیر در بدنه تابع با الحاق رشته “Hello” به متغیر $name با استفاده از . عملگر الحاق رشته ها اکنون تابع نیاز دارد که هنگام فراخوانی تابع، یک ورودی ارسال شود، اما ورودی ارائه نشده است، و باعث می شود PHP با خطا پاسخ دهد:

Output
Warning:  Uncaught ArgumentCountError: Too few arguments to function hello(), 0 passed in php shell code on line 1 and exactly 1 expected

هنگامی که تابع hello فراخوانی می شود، برای استفاده به عنوان ورودی نیاز به یک آرگومان دارد که مقدار $name را تعیین می کند. اصطلاح پارامتر زمانی استفاده می شود که بخشی از تعریف تابع باشد و اصطلاح آرگومان زمانی استفاده می شود که بخشی از فراخوانی تابع باشد. هر دو به ورودی یک تابع اشاره دارند. برای ارائه ورودی به تابع، یک آرگومان بین پرانتز فراخوانی تابع ارسال می کنیم:

hello.php
<?php
function hello($name) {
    echo "Hello ".$name;
}
hello("Sammy");

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

Output
Hello Sammy

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

مقادیر پیش فرض اختیاری

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

hello.php
<?php
function hello($name, $greeting = "Hello") {
    echo $greeting." ".$name;
}
hello("Sammy", "Bonjour");

اکنون یک پارامتر دوم به نام $greeting وجود دارد. سپس این متغیر در بدنه تابع برای تغییر مقدار بخش تبریک خروجی استفاده می شود:

Output
Bonjour Sammy

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

hello.php
<?php
function hello($name, $greeting = "Hello") {
    echo $greeting." ".$name;
}
hello("Sammy");

هنگامی که تنها یک آرگومان ارسال می شود، مقدار متغیر $greeting روی مقدار پیش فرض “Hello” تنظیم می شود:

Output
Hello Sammy

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

مقدار تهی اختیاری

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

hello.php
<?php
function hello($name, $greeting = "Hello", $punctuation = null) {
    echo $greeting." ".$name.$punctuation;
}
hello("Sammy");

متغیر is “اعلام شده” است، بنابراین هنگام تلاش بدنه تابع برای دسترسی به متغیر، خطایی وجود نخواهد داشت، و با این حال، متغیر “تنظیم نشده” در نظر گرفته می شود، بنابراین خروجی اضافی اضافه نخواهد شد:

Output
Hello Sammy

ارزش های بازگشتی

ممکن است همیشه نخواهیم خروجی یک تابع را چاپ کنیم. برای ایجاد انعطاف‌پذیری بیشتر در یک تابع، معمول است که مقدار خروجی را به کدی که در ابتدا فراخوانی تابع را انجام داده است، برگردانید. به جای کلمه کلیدی echo از کلمه کلیدی return استفاده کنید:

hello.php
<?php
function hello($name, $greeting = "Hello", $punctuation = null) {
    return $greeting." ".$name.$punctuation;
}
hello("Sammy");
echo hello("Sammy");

در اولین فراخوانی تابع hello، هیچ کاری با مقدار برگشتی انجام نمی شود، و به نظر می رسد که هیچ اتفاقی نیفتاده است، حتی اگر کد موجود در تابع اجرا شده باشد. در فراخوانی دوم تابع hello، کلمه کلیدی echo قبل از فراخوانی تابع استفاده می‌شود و به PHP می‌گوید نتایج خروجی برگشتی را چاپ کند:

Output
Hello Sammy

ما همیشه مجبور نیستیم نتیجه را چاپ کنیم. این نتایج همچنین می توانند در یک متغیر ذخیره شوند یا به عنوان ورودی برای تابع دیگری استفاده شوند.

فراخوانی توابع در یک تابع

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

hello.php
<?php
function hello($name, $greeting = "Hello", $punctuation = null) {
    $name = ucwords(strtolower($name));
    return $greeting." ".$name.$punctuation;
}
echo hello("SAMMY");

خط اول در تابع hello اکنون مقداری قالب بندی برای مقدار $name اعمال می کند. ابتدا رشته را به حروف کوچک تبدیل می کند. تابع strtolower مقداری را برمی گرداند که بلافاصله در تابع دوم، ucwords استفاده می شود. این حرف اول هر کلمه را به حروف بزرگ تبدیل می کند. تابع hello اکنون بدون در نظر گرفتن ورودی دریافتی، یک خروجی با فرمت ثابت ارائه می دهد:

Output
Hello Sammy

اعلانات نوع

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

hello.php
<?php
function hello($name, $greeting = "Hello", $punctuation = null) {
    $name = ucwords(strtolower($name));
    return $greeting." ".$name.$punctuation;
}
echo hello(123);

PHP هیچ گونه مشکلی در شعبده بازی ندارد، که عدد صحیح 123 را به رشته “123” تبدیل می کند، سپس تابع را مانند قبل ادامه می دهد:

Output
Hello 123

این خروجی معتبر است، اما احتمالاً این نیز نتیجه مطلوب نیست. بیایید ببینیم وقتی یک آرایه را پاس می کنیم چه اتفاقی می افتد. تابع stringtolower یک خطای متفاوت ایجاد می کند. برای این نمایش، اسلش‌های دوتایی به ابتدای آن خط اضافه می‌شود تا آن را به عنوان یک نظر تبدیل کند، که اجرای آن کد را رد می‌کند:

hello.php
<?php
function hello($name, $greeting = "Hello", $punctuation = null) {
    // $name = ucwords(strtolower($name));
    return $greeting." ".$name.$punctuation;
}
echo hello(["Sammy", "World"]);

این بار کد یک اطلاعیه ارائه می دهد، اما خیلی واضح نیست. همچنین، بسته به نحوه راه‌اندازی سیستم، اعلان‌ها می‌توانند خاموش یا نادیده گرفته شوند زیرا اجرای کد را متوقف نمی‌کنند. ممکن است متوجه نباشیم که مشکلی وجود دارد، یا ممکن است در تشخیص محل وقوع مشکل با مشکل مواجه شویم. خروجی به نظر می رسد که گویی رشته “Array” به تابع ارسال شده است:

Output
Notice: Array to string conversion in php shell code on line 2
Hello Array

توسعه دهندگان زمان بسیار بیشتری را صرف خواندن و اشکال زدایی می کنند تا اینکه واقعاً کد بنویسند، بنابراین هر کدی را که می نویسیم تا حد امکان برای خواندن و اشکال زدایی آسان تر کنیم، در دراز مدت در زمان صرفه جویی می شود. با شروع در PHP 5 و با پشتیبانی قوی تر در PHP 7، اکنون می توانیم انواع مقادیر قابل قبول ورودی و خروجی یک تابع را اعلام یا مشخص کنیم.

اعلان نوع پارامتر

اعلان‌های نوع پارامتر تضمین می‌کنند که مقدار آرگومان که هنگام فراخوانی تابع استفاده می‌شود، با نوع مشخص شده مطابقت دارد. در غیر این صورت، یک TypeError پرتاب می شود. بیایید نوع رشته را به پارامتر $name خود اضافه کنیم و آرگومان های آرایه را دوباره امتحان کنیم. این بار می توانیم خط stringtolower را نگه داریم زیرا به آن کد دسترسی پیدا نمی کند:

hello.php
<?php
function hello(string $name, $greeting = "Hello", $punctuation = null) {
    $name = ucwords(strtolower($name));
    return $greeting." ".$name.$punctuation;
}
echo hello(["Sammy", "World"]);

این بار فراخوانی تابع باعث ایجاد یک استثنا می شود که اجرای کد را متوقف می کند، بنابراین خروجی معتبری به نظر نمی رسد. پیام همچنین واضح تر است که خطا در واقع وجود دارد:

Output
Warning: Uncaught TypeError: Argument 1 passed to hello() must be of the type string, array given

اگر آرگومان به جای آرایه به عدد صحیح برگردد، منطقی است که انتظار خطا داشته باشیم زیرا پارامتر فقط باید مقادیر رشته را بپذیرد. بیایید آن را امتحان کنیم:

hello.php
<?php
function hello(string $name, $greeting = "Hello", $punctuation = null) {
    $name = ucwords(strtolower($name));
    return $greeting." ".$name.$punctuation;
}
echo hello(123);

به جای ارسال خطا، یک بار دیگر عدد صحیح بدون مشکل به رشته تبدیل می شود و تابع اجرا می شود:

Output
Hello 123

این مربوط به این است که PHP یک زبان تایپ آزاد است. PHP هنوز هم برای تبدیل آن به یک رشته، شعبده برداری از نوع را روی عدد صحیح انجام می دهد، سپس اجرا را ادامه می دهد.

انواع سختگیرانه

ممانعت از اجرای «جلوگیری نوع» توسط PHP می‌تواند در آسان‌تر خواندن کد و اشکال‌زدایی مفید باشد. پی اچ پی راهی را برای ما فراهم می کند تا انواع سخت گیرانه را بر اساس هر فایل اعلام کنیم. اعلان را به بالای هر فایلی که باید تایپ دقیق را اعمال کند اضافه کنید:

hello.php
<?php
declare(strict_types=1);
function hello(string $name, $greeting = "Hello", $punctuation = null) {
    $name = ucwords(strtolower($name));
    return $greeting." ".$name.$punctuation;
}
echo hello(123);

پس از افزودن خط اعلان به بالای فایل، PHP هنگامی که یک عدد صحیح به جای رشته ارسال می شود، یک خطا ایجاد می کند:

Output
PHP Fatal error:  Uncaught TypeError: Argument 1 passed to hello() must be of the type string, int given.

انواع Nullable

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

hello.php
<?php
declare(strict_types=1);
function hello(string $name, string $greeting = "Hello", string $punctuation = null) {
    $name = ucwords(strtolower($name));
    return $greeting." ".$name.$punctuation;
}
echo hello("SAMMY", "Hola", null);

از آنجایی که مقدار پیش‌فرض پارامتر سوم روی null تنظیم شده است، آرگومان null و همچنین یک رشته مجاز است:

Output
Hola Sammy

با این حال، هنگامی که مقدار پیش فرض یک پارامتر به عنوان یک رشته اعلام می شود، دیگر مقدار تهی را نمی پذیرد:

hello.php
<?php
declare(strict_types=1);
function hello(string $name, string $greeting = "Hello", string $punctuation = "!") {
    $name = ucwords(strtolower($name));
    return $greeting." ".$name.$punctuation;
}
echo hello("SAMMY", "Hola", null);

در عوض TypeError داده می شود:

Output
Warning: Uncaught TypeError: hello(): Argument #3 ($punctuation) must be of type string, null given

وقتی مقدار پیش‌فرض یک پارامتر چیزی غیر از null باشد، اما null نیز یک ورودی معتبر باشد، PHP دستور اضافی را برای تعریف آن رابطه با اضافه کردن یک علامت سوال قبل از اعلان نوع ارائه می‌کند:

hello.php
<?php
declare(strict_types=1);
function hello(string $name, string $greeting = "Hello", ?string $punctuation = null) {
    $name = ucwords(strtolower($name));
    return $greeting." ".$name.$punctuation;
}
echo hello("SAMMY", "Hola", null);

حالا تابع آرگومان سوم null را می پذیرد و همانطور که قبلا پردازش شده است ادامه می دهد:

Output
Hola Sammy!

پیشوند علامت سوال با تمام اعلان‌های نوع کار می‌کند، نه فقط رشته‌ها، و نیازی به مقدار پیش‌فرض (مانند ?int $age) ندارد.

اعلامیه های نوع بازگشت

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

hello.php
<?php
declare(strict_types=1);
function hello(string $name, string $greeting = "Hello", ?string $punctuation = "!"): ?int {
    $name = ucwords(strtolower($name));
    return $greeting." ".$name.$punctuation;
}
echo hello("SAMMY");

توجه داشته باشید که نوع بازگشتی اعلام شده یک عدد صحیح یا یک مقدار تهی است. این نوع اعلام شده با مقدار بازگشتی آنها مطابقت ندارد و یک استثنا ایجاد می شود:

Output
Warning: Uncaught TypeError: hello(): Return value must be of type ?int, string returned

بیایید نوع بازگشتی را به روز کنیم تا با نوع رشته برگشتی مطابقت داشته باشد:

hello.php
<?php
declare(strict_types=1);
function hello(string $name, string $greeting = "Hello", ?string $punctuation = "!"): string {
    $name = ucwords(strtolower($name));
    return $greeting." ".$name.$punctuation;
}
echo hello("SAMMY");

این خروجی را به ما می دهد که قبلاً دیده بودیم:

Output
Hello Sammy!

بدون ارزش برگشتی

گاهی اوقات یک تابع عملی را انجام می دهد که به مقدار برگشتی منجر نمی شود. تابع var_dump یک مثال است. اگر به اولین نسخه تابع hello برگردیم، می‌توانیم یک نوع بازگشتی void اضافه کنیم:

hello.php
<?php
function hello(): void {
    echo "Hello World!";
}
$greeting = hello();
var_dump($greeting);

این نشان می دهد که تابع مقداری را بر نمی گرداند. هنگامی که تابع فراخوانی می شود و روی یک متغیر اعمال می شود، خروجی نمایش داده می شود زیرا کلمه کلیدی echo در خود تابع استفاده می شود. با استفاده از var_dump در متغیر $greeting، می‌بینیم که هیچ مقداری برگردانده نشده است و متغیر $greeting روی یک مقدار null تنظیم می‌شود:

Output
Hello World!
NULL

نوع void بیشتر هنگام دستکاری خود متغیر و نه فقط یک مقدار استفاده می شود. برای آن، ما باید دامنه را درک کنیم.

محدوده

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

در برنامه نویسی، دامنه به نحوه دسترسی قطعات مختلف کد به یکدیگر اشاره دارد. چندین حوزه مختلف در یک برنامه کاربردی وجود دارد. برای هدف توابع، دو مورد از آنها را بررسی می کنیم – دامنه جهانی فایل و محدوده تابع.

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

از آنجایی که PHP این دو حوزه را به‌عنوان موجودیت‌های مجزا در نظر می‌گیرد، زمانی که یک متغیر به یک تابع ارسال می‌شود، «مقدار» متغیر ارسال می‌شود و نه خود متغیر. بیایید یک متغیر سراسری تنظیم کنیم تا ببینیم این به چه معناست برای کد:

hello.php
<?php
declare(strict_types=1);
$name = "SAMMY";
function hello(string $name, string $greeting = "Hello", ?string $punctuation = "!"): string {
    $name = ucwords(strtolower($name));
    return $greeting." ".$name.$punctuation;
}
echo hello($name);
echo $name;

به جای ارسال مستقیم یک رشته، اکنون یک متغیر رشته را ارسال می کنیم. این متغیر به همان شیوه ای عمل می کند که یک رشته را به طور مستقیم ارسال می کند زیرا فقط از مقدار متغیر استفاده می شود. هنگامی که مقدار متغیر $name در تابع تغییر می کند، فقط متغیر $name در تابع تحت تأثیر قرار می گیرد. متغیر $name در دامنه جهانی یک متغیر جداگانه است:

Output
Hello Sammy!
SAMMY

خروجی echo hello($name) “Hello Sammy” است، زیرا این مقداری است که توسط تابعی که با آرگومان $name ارائه شده است، برگردانده می شود. حتی پس از فراخوانی تابع، مقدار متغیر $name در محدوده جهانی تغییر نمی کند، بنابراین خروجی echo $name; “SAMMY” است، زیرا متغیر جهانی روی “SAMMY” تنظیم می شود.

دسترسی به گستره جهانی

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

hello.php
<?php
declare(strict_types=1);
$name = "SAMMY";
function hello(string $greeting = "Hello", ?string $punctuation = "!"): string {
    global $name;
    $name = ucwords(strtolower($name));
    return $greeting." ".$name.$punctuation;
}
echo hello();
echo $name;

متغیر $name در دامنه جهانی تنظیم شده است، اما به جای ارسال مقدار به تابع، اکنون خط اول تابع برای گرفتن متغیر از دامنه جهانی می رسد. کلمه کلیدی سراسری خود متغیر و نه فقط مقدار آن را می گیرد. قالب‌بندی انجام شده در تابع به دامنه جهانی متغیر اعمال می‌شود که مقدار متغیر خارج از تابع را نیز تغییر می‌دهد:

Output
Hello Sammy!
Sammy

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

گذراندن استدلال ها با مرجع

پی اچ پی آرگومان ها را به عنوان مقادیر می خواند. فرقی نمی‌کند که متغیری حاوی رشته «SAMMY» یا خود رشته را پاس کنیم. فقط از مقدار استفاده می شود. عبور از مقدار از همپوشانی دامنه جهانی و دامنه عملکرد جلوگیری می کند. از آنجا که یک تابع ممکن است مقداری را برگرداند، می‌توانیم از آن مقدار برای تنظیم هر متغیری در یک محدوده جداگانه استفاده کنیم، حتی یکی از آن‌ها به عنوان آرگومان استفاده می‌شود. با نوشتن کد به این روش، مدیریت یک متغیر به وضوح در محدوده اصلی نگهداری می شود. مثال‌های قبلی مقدار متغیر $name را با نادیده گرفتن مقدار متغیر برای مطابقت با مقدار بازگشتی برخی از توابع داخلی تغییر داده‌اند. بیایید نگاهی دقیق‌تر به قالب‌بندی ucwords و strtolower بیندازیم:

$name = "SAMMY";
$name = ucwords(strtolower($name));
echo $name;

این مقدار جدید $name اکنون قالب بندی جدیدی دارد:

Output
Sammy

در حالی که یک تابع فقط می تواند یک مقدار را برگرداند، یک تابع ممکن است بیش از یک متغیر را تحت تأثیر قرار دهد. در مثال‌هایی که نوشتیم، تابع hello از چندین متغیر استفاده می‌کند اما مقدار آن متغیرها را در محدوده جهانی تغییر نمی‌دهد. PHP راهی را برای تعامل مستقیم با یک متغیر از محدوده دیگر، با ارسال یک مرجع به خود متغیر، نه فقط مقدار آن، فراهم می کند. آرگومان ها با ارجاع با افزودن علامت (&) به هر پارامتری منتقل می شوند:

hello.php
<?php
declare(strict_types=1);
$name = "SAMMY";
function hello(string &$name, string $greeting = "Hello", ?string $punctuation = "!"): void {
    $name = ucwords(strtolower($name));
    return $greeting." ".$name.$punctuation;
}
echo hello($name);
echo $name;

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

Output
Hello Sammy!
Sammy

هنگام عبور از مرجع، آرگومان باید یک متغیر باشد. یک مقدار دیگر پذیرفته نمی شود:

hello.php
<?php
declare(strict_types=1);
function hello(string &$name, string $greeting = "Hello", ?string $punctuation = "!"): string {
    global $name;
    $name = ucwords(strtolower($name));
    return $greeting." ".$name.$punctuation;
}
echo hello("SAMMY");

از آنجایی که هیچ متغیری برای مرجع وجود ندارد، یک خطا داده می شود:

Output
Warning: Uncaught Error: hello(): Argument #1 ($name) cannot be passed by reference

توابع داخلی

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

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

توابع مدیریت متغیر

توابع مدیریت متغیر جزئیاتی را در مورد یک متغیر مانند نوع یا مقدار آن ارائه می دهند. یکی از رایج ترین توابع مدیریت متغیر var_dump است:

hello.php
<?php
var_dump("Hello World!");

این تابع جزئیات مقادیر داده شده را شامل نوع و اندازه آنها می دهد. رشته “سلام دنیا!” شامل 12 کاراکتر:

Output
string(12) "Hello World!"

PHP همچنین توابع اضافی را برای تعامل با مقدار متغیرهای نوع خاص فراهم می کند.

نتیجه

توابع روشی قدرتمند برای نوشتن کدی که ماژولار و قابل استفاده مجدد است ارائه می دهد. توابع ممکن است از توزیع استاندارد PHP یا پسوندهای اضافی که با PHP کامپایل شده اند باشد. توسعه دهندگان فردی همچنین ممکن است توابعی را برای یک پروژه بنویسند یا آنها را در چندین پروژه به اشتراک بگذارند. هنگامی که به یک عمل نیاز دارید که علیه بیش از یک مورد یا مکان انجام شود، توابع ابزار هستند.

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


سرور مجازی آلمان

سرور مجازی آمریکا

سرور مجازی فرانسه

سرور مجازی کانادا

سرور مجازی لهستان

سرور مجازی هلند

سرور مجازی انگلیس

 

برچسب‌ها:, , , , , , , , ,