التحميل التلقائي (autoloading) كجزء من حل إطار العمل
ملف autoload.php
:
spl_autoload_register(function ($class) { require_once "$class.php"; });
ملف Animal.php
:
class Animal { public function eats($food) { echo "Yum, $food!"; } }
ملف Ruminant.php
:
class Ruminant extends Animal { public function eats($food) { if ('grass' === $food) { parent::eats($food); } else { echo "Yuck, $food!"; } } }
ملف Cow.php
:
class Cow extends Ruminant { }
ملف pasture.php
:
require 'autoload.php'; $animal = new Cow; $animal->eats('grass');
يمكننا الوصول إلى أي صنف يتبع اصطلاحات التسمية الموجودة في المحمِّل التلقائي وذلك بفضل المحمل التلقائي العام. اصطلاحاتنا في هذا المثال بسيطة: يجب أن يكون للصنف المطلوب ملف في نفس المجلد يُسمّى بنفس اسم الصنف وتُضاف له اللاحقة .php
، يجب أن يكون اسم الصنف مطابقًا تمامًا لاسم الملف.
بدون التحميل التلقائي، يجب أن نضيف الأصناف الأساسية يدويًا باستخدام require
، إذا كنا نبني حديقة حيوانات كاملة سيكون لدينا الآلاف من تعليمات require
التي يمكن استبدالها بسهولة بمحمِّل تلقائي واحد.
في التحليل النهائي، يعدّ التحميل التلقائي في PHP آلية تساعدك على كتابة شيفرة بآلية أقل لذا يمكنك التركيز على حل مشاكل العمل، كل ماعليك فعله هو تحديد استراتيجية تربط اسم الصنف باسم الملف، يمكنك تنفيذ استراتيجية تحميل تلقائي خاصة بك كما هو الحال هنا، أو يمكنك استخدام أي من المعايير التي تتبناها PHP: PSR-0 أوPSR-4 أو يمكنك استخدام المُنشئ لتعريف الاعتماديات وإدارتها بشكلٍ عام.
تعريف صنف مضمَّن بدون الحاجة للتحميل
ملف zoo.php
:
class Animal { public function eats($food) { echo "Yum, $food!"; } } $animal = new Animal(); $animal->eats('meat');
تعلم PHP ماهو الصنف Animal
قبل تنفيذ التعليمة new Animal
لأن PHP تقرأ الملفات المصدرية من الأعلى إلى الأسفل، لكن ماذا لو أردنا إنشاء كائنات من الصنف Animal
في عدة أماكن ليس فقط في الملف المصدري الذي عُرِّف فيه، نحتاج للقيام بذلك إلى تحميل تعريف الصنف.
تحميل يدوي للصنف باستخدام require
ملف Animal.php
:
class Animal { public function eats($food) { echo "Yum, $food!"; } }
ملف zoo.php
:
require 'Animal.php'; $animal = new Animal; $animal->eats('slop');
ملف aquarium.php
:
require 'Animal.php'; $animal = new Animal; $animal->eats('shrimp');
لدينا ثلاثة ملفات، يعرّف الملف الأول "Animal.php" الصنف، ويجمع كل المعلومات المتعلقة بالحيوان في مكان واحد بشكلٍ أنيق، ليس لهذا الملف آثار جانبية، هذه نسخة قابلة للتحكم ويمكن إعادة استخدامها بسهولة.
يستخدم الملفان الآخران هذا الملف بتضمينه يدويًا، وبما أنّ PHP تقرأ الملف المصدري من الأعلى إلى الأسفل فإنّ تعليمة require
ستجد الملف "Animal.php" وتجعل تعريف الصنف Animal
متوفرًا قبل استدعاء new Animal
.
تخيل الآن أنّه لديك عشرات أو مئات الحالات التي تريد فيها إنشاء كائنات جديدة من الصنف Animal
قد يتطلب ذلك الكثير من تعليمات require
المملة.
التحميل التلقائي بديلًا لتحميل تعريف الصنف يدويًا
ملف autoload.php
:
spl_autoload_register(function ($class) { require_once "$class.php"; });
ملف Animal.php
:
class Animal { public function eats($food) { echo "Yum, $food!"; } }
ملف zoo.php
:
require 'autoload.php'; $animal = new Animal; $animal->eats('slop');
ملف aquarium.php
:
require 'autoload.php'; $animal = new Animal; $animal->eats('shrimp');
وازن هذا المثال مع الأمثلة الأخرى، ولاحظ كيف استبدلنا التعليمة require "Animal.php"
بالتعليمة require "autoload.php"
، مازلنا نضمن الملف الخارجي في وقت التنفيذ لكن بدلًا من تضمين تعريف صنف معين نضمّن منطق يمكن أن يحتوي على أي صنف وهذا يسهّل عملية التطوير،إذ نكتب تعليمة require
واحدة لكل الأصناف بدلًا من كتابتها لكل صنف على حدة.
يحدث السحر باستخدام spl_autoload_register، إذ تأخذ هذه الدالة مغلِّف وتضيفه إلى رتل من المغلِّفات، عندما تصادف PHP صنفًا ليس له تعريف فإنها تعطي اسم الصنف إلى كل مغلِّف في الرتل، إذا وِجد الصنف بعد استدعاء مغلِّف ما فإنّ PHP تعود إلى عملها السابق، وإذا لم يوجد الصنف بعد تجربة كامل الرتل تتعطل PHP وتطلق الخطأ "Class 'Whatever' not found."
التحميل التلقائي مع المُنشِئ
يولِّد المُنشئ الملف vendor/autoload.php
، يمكنك تضمين هذا الملف ببساطة وستحصل على التحميل التلقائي مجانًا.
require __DIR__ . '/vendor/autoload.php';
وهذا يجعل العمل مع اعتماديات من طرف ثالث (third-party dependencies) سهل جدًا، ويمكنك أن تضيف أيضًا شيفرتك الخاصة إلى المحمِّل التلقائي بإضافة قسم تحميل تلقائي إلى composer.json
.
{ "autoload": { "psr-4": {"YourApplicationNamespace\\": "src/"} } }
تحدد في هذا القسم رابط التحميل التلقائي، يربط هذا المثال PSR-4 فضاء اسم إلى مجلد، يبقى المجلد /src
في المجلد الجذر لمشاريعك في نفس المستوى الموجود فيه المجلد /vendor
، يمكن أن يكون لديك اسم الملف src/Foo.php
مثلًا والذي يحتوي على الصنف YourApplicationNamespace\Foo
.
ملاحظة: بعد إضافة مداخل جديدة إلى قسم التحميل التلقائي يجب إعادة تنفيذ الأمر dump-autoload لإعادة توليد وتحديث الملف vendor/autoload.php
بالمعلومات الجديدة.
يدعم المُنشئ التحميل التلقائي للمعيار PSR-0 وclassmap
وfiles
بالإضافة إلى PSR-4، يمكنك الاطلاع على مرجع التحميل التلقائي لمزيد من المعلومات.
عند تضمين الملف vendor/autoload.php
ستُرجع نسخة من المحمِّل التلقائي للمُنشئ، يمكنك تخزين القيمة المُرجعة من استدعاء التضمين في متغير وإضافة المزيد من فضاءات الأسماء، يمكن أن يكون هذا مفيدًا في التحميل التلقائي للأصناف في مجموعة الاختبار، مثال:
$loader = require __DIR__ . '/vendor/autoload.php'; $loader->add('Application\\Test\\', __DIR__);
إنشاء ملفات PDF في PHP
مكتبة PDFlib
تتطلب الشيفرة التالية استخدام مكتبة PDFlib لتعمل بشكلٍ صحيح.
<?php // تهيئة كائن جديد $pdf = pdf_new(); // إنشاء ملف pdf فارغ جديد pdf_begin_document($pdf);? // ضبط معلومات الملف pdf_set_info($pdf, "Author", "John Doe"); pdf_set_info($pdf, "Title", "HelloWorld"); // تحديد طول وعرض الصفحة pdf_begin_page($pdf, (72 * 8.5), (72 * 11)); // تحميل خط $font = pdf_findfont($pdf, "Times-Roman", "host", 0) // ضبط الخط pdf_setfont($pdf, $font, 48); // تعيين موضع النص pdf_set_text_pos($pdf, 50, 700); // طباعة النص إلى الموضع المحدد pdf_show($pdf, "Hello_World!"); // نهاية الصفحة pdf_end_page($pdf); // إغلاق الكائن pdf_end_document($pdf); // استعادة المحتويات من المخزن المؤقت $document = pdf_get_buffer($pdf); // إيجاد طول ملف PDF وتعيين اسم للملف $length = strlen($document); $filename = "HelloWorld.pdf"; header("Content-Type:application/pdf"); header("Content-Length:" . $length); header("Content-Disposition:inline; filename=" . $filename); // إرسال الملف إلى المتصفح echo($document); // مسح الذاكرة unset($document); pdf_delete($pdf); ?>
مكتبة YAML
تثبيت الإضافة YAML
لا تأتي إضافة YAML مع تثبيت PHP القياسي، بل يجب تثبيتها كإضافة PECL، ويمكن القيام بذلك في لينوكس/يونكس ببساطة:
pecl install yaml
لاحظ أنّ الحزمة libyaml-dev
يجب أن تكون مثبتة على النظام لأنّ حزمة PECL هي مجرد غلاف لاستدعاءات libYAML.
يختلف التثبيت على ويندوز، إذ يمكنك تحميل DLL المصرَّف مسبقًا أو بناؤه من المصدر.
استخدام YAML لتخزين إعدادات التطبيق
توفر مكتبة YAML طريقةً لتخزين البيانات المهيكلة، يمكن أن تكون البيانات مجموعة بسيطة من الأزواج اسم-قيمة أو بيانات هرمية معقدة مع قيم أو قد تكون مصفوفات.
بفرض لدينا ملف YAML التالي:
database: driver: mysql host: database.mydomain.com port: 3306 db_name: sample_db user: myuser password: Passw0rd debug: true country: us
بفرض أننا حفظناه كملف config.yaml
، لقراءة هذا الملف باستخدام PHP نستخدم الشيفرة التالية:
$config = yaml_parse_file('config.yaml'); print_r($config);
سينتج الخرج التالي:
Array ( [database] => Array ( [driver] => mysql [host] => database.mydomain.com [port] => 3306 [db_name] => sample_db [user] => myuser [password] => Passw0rd ) [debug] => 1 [country] => us )
يمكن الآن استخدام معاملات الإعدادات ببساطة باستخدام عناصر المصفوفة:
$dbConfig = $config['database']; $connectString = $dbConfig['driver'] . ":host={$dbConfig['host']}" . ":port={$dbConfig['port']}" . ":dbname={$dbConfig['db_name']}" . ":user={$dbConfig['user']}" . ":password={$dbConfig['password']}"; $dbConnection = new \PDO($connectString, $dbConfig['user'], $dbConfig['password']);
ترجمة -وبتصرف- للفصول [ Autoloading Primer - Create PDF files in PHP - YAML in PHP] من كتاب PHP Notes for Professionals book
اقرأ أيضًا
- المقال السابق: التخزين المؤقت (Cache) ومقابس الويب (Webscockets) في PHP
أفضل التعليقات
لا توجد أية تعليقات بعد
انضم إلى النقاش
يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.