اذهب إلى المحتوى

لوحة المتصدرين

  1. Abdourabih Tahtah

    Abdourabih Tahtah

    الأعضاء


    • نقاط

      6

    • المساهمات

      36


  2. عبد اللطيف ايمش

    • نقاط

      3

    • المساهمات

      1406


  3. محمد بدرالدين

    محمد بدرالدين

    الأعضاء


    • نقاط

      1

    • المساهمات

      3


  4. أحمد النوبي

    أحمد النوبي

    الأعضاء


    • نقاط

      1

    • المساهمات

      92


المحتوى الأكثر حصولًا على سمعة جيدة

المحتوى الأعلى تقييمًا في 04/24/17 في كل الموقع

  1. قبل البدء بتوضيح كيفية استخدام Codeception مع شيفرات PHP، فيجب أن نغطي الأساسيات عبر شرحنا لماذا نحتاج إلى اختبار تطبيقاتنا. ربما يمكننا إكمال المشروع الذي نعمل عليه دون تضييع الوقت بكتابة الاختبارات، أليس ذلك؟ بلى، إذ لن تحتاج إلى كتابة اختبارات لكل شيء (كإنشاء صفحة رئيسية لموقعك). لن تحتاج غالبًا إلى كتابة اختبارات عندما يحتوي مشروعك على صفحات ثابتة مرتبطة بصفحة توجيه وحيدة. لكنك ستحتاج إلى إجراء اختبارات عندما: يستخدم فريقك أسلوب «التطوير الموجّه بالاختبارات» (TDD) أو «التطوير الموجّه بالسلوك» (BDD). تُجرى عدِّة عمليات إيداع في مستودع Git التابع لمشروعك يوميًا. أنت مطوِّرٌ محترف، وتعمل على مشروع جاد. يمكنك أن تعذر نفسك بقولك أنَّ هنالك فريق كامل مخصص للاختبارات، وهم مجموعةٌ من الأشخاص الذين يجرون اختبارات ويكتبونها عند الحاجة. لكن لك أن تتخيل كم سيستغرق حلّ العلّة من الوقت بعد أن تضيف وظائف جديدة إلى مشروعك. ما المشاكل التي تحلها الاختبارات؟ لنتعرّف أولًا على المشاكل التي يمكن حلها عبر الاختبارات. لن تتمكن من التخلص من جميع الأخطاء الظاهرة عند الاختبار، لكنك ستستطيع توصيف السلوك المتوقع في حالات الاختبار (test cases). انتبه إلى أنَّه قد توجد أخطاء ضمن حالات الاختبار التي تكتبها. لكن كن على يقين أنَّ شيفرتك ستتغير فيما بعد (إما بتصحيح العلل، أو إضافة ميزات جديدة، حتى تصبح شيفرتك خاليةً من الأخطاء الموصوفة في حالة الاختبار). يمكن -إضافةً إلى ما سبق- استعمال حالات الاختبار المكتوبة بشكلٍ جيد في التوثيق لأنك سترى من خلالها ما هو السلوك المتوقع للبرنامج في حالات معيّنة. خلاصة القول أنَّ كتابة الاختبارات هي استثمارٌ مهمٌ تستفيد منه في المستقبل. إذًا، ما هي الاختبارات التي يمكننا استعمالها في مشروعنا؟ اختبارات الوحدات (unit tests): هي اختباراتٌ منخفضة المستوى (low-level) التي تتحقق من سلامة أجزاء صغيرة من شيفرتك، والتي تكون عادةً الدوال الموجودة في الأصناف (classes) الموجودة في مشروعك والمعزولة عن بعضها. اختبارات التكامل (integration tests): تتحقق اختبارات التكامل من سلامة أداء جزءٍ من برنامجك والذي قد يحتوي على عدِّة أصناف أو دوال، إلا أنها تؤدي جميعًا غرضًا وحيدًا ألا وهو توفير ميزة معيّنة. يجب أن تتحقق هذه الاختبارات من كيفية تفاعل الأصناف مع بعضها. الاختبارات الوظيفية (function tests): اختبار استجابة التطبيق لمختلف الطلبيات، كالتغيرات الحاصلة في قاعدة البيانات ...إلخ. اختبارات القبول (acceptance tests): الغرض من هذه الاختبارات في أغلبية الحالات هو معرفة إن كان التطبيق يلبّي جميع متطلبات العميل. للتوضيح، لنحاول شرح هذه العملية بتمثيلها على شيءٍ ملموس مثل المباني. تتألف بعض أنواع المباني من لبنات صغيرة تُشكِّل جدرانًا، ويجب أن تتحقق اشتراطاتٌ معيّنةٌ فيها، إذ يجب أن تستطيع أن تقاوم الحِمل المُطبَّق عليها، ويجب أن تكون لها أبعاد وحجم معيّن وهلم جرًا… تلك الأمور تسمى «اختبارات الوحدات» (unit tests). أما الفكرة من اختبارات الاندماج هي معرفة متانة وقوة الارتباط بين اللّبنات، وكيف تُشكِّل مع بعضها عنصرًا من عناصر المبنى (مثل الجدران). أما الاختبارات الوظيفية فيمكن ربطها بالاختبارات التي تُجرى على جدارٍ من جدران المبنى، مثل اختبار جودة العزل الحراري، ومعرفة إن كان بالإمكان مرور أشعة الشمس من النوافذ الموجودة في هذا الجدار. وأخيرًا، تتضمن اختبارات القبول إجراء فحص لكامل المبنى: كفتح الباب، والدخول إلى الغرفة، وإغلاق الباب، وتشغيل الضوء، والصعود إلى الطابق الثاني والنظر إلى الحديقة عبر النافذة… تعرّف على Codeception التقسيم السابق مشروطٌ بعدِّة عوامل، ويصعب مقاومة النزعة إلى خلط عدِّة أنواع من الاختبارات. يستعمل الكثير من المبرمجين اختبارات الوحدات ويدّعون أنها كافية؛ وكنتُ منهم، إلا أنني وجدتُ أنَّ استخدام عدِّة أنظمة لمختلف أنواع الاختبارات هو أمرٌ مرهقٌ ويستهلك وقتًا طويلًا. لذا قررتُ منذ فترة أن أعثر على شيءٍ أكثر فائدةً من مكتبة PHPUnit؛ أردتُ أن يتطور استخدامي لاختبارات الشيفرات، إلا أنني لم أرغب بقراءة وتعلم الكثير من صفحات التوثيق وأن أبحث عن الحلول الالتفافية للمشاكل التي تواجهني. ومن ثم اكتشفت وجود Codeception. كنتُ بادئ الأمر متشككًا ومرتابًا منه، وهذه طبيعتنا عندما نرى شيئًا جديدًا (الحق يقال: هذا المشروع موجودٌ منذ خمس سنوات، لذا لا يمكننا اعتباره «جديدًا»)، لكن بعد تجربته لعدة أيام، خَلِصتُ إلى أنَّ Codeception هو نظامٌ مفيدٌ جدًا. قد تتساءل كيف تستطيع تثبيت Codeception؟ الأمر أبسط مما تتخيل: $ composer require "codeception/codeception" $ php vendor/bin/codecept bootstrap بعد التثبيت ستجد مجلدًا جديدًا باسم test في مشروعك، وستجد داخله مجلداتٍ فرعيةً باسم acceptance و functional و unit، يبدو أننا نستطيع البدء بكتابة اختباراتنا، إذًا ما هي الخطوة القادمة؟ لنحاول الآن إضافة اختبار قبول لمثالٍ بسيط: $ php vendor/bin/codecept generate:cept acceptance HelloWorld يمكننا الآن فتح ملف اختبار القبول ذي المسار tests/acceptance/HelloWorldCept.php ونضع فيه المحتوى الآتي: <?php $I = new AcceptanceTester($scenario); $I->wantTo('perform actions and see result'); المتغير الافتراضي المسمى ‎$I ليس مجرد حرف، وإنما هو ضمير متحدث يُشير إلى «الشخص» الذي يجري الاختبار: الذي يفتح صفحة تطبيقك أو أحد أصنافه ويفعل شيئًا ما ويريك النتيجة النهائية لأفعاله. إذ سترى ماذا فعل وما هو الخطأ الذي حدث. هذا هو سبب تسمية ذاك الكائن بالاسم ‎$I ولماذا تدعى الدوال الموجودة فيه wantTo()‎ و see()‎ و amOnPage()‎. لنفكر كشخصٍ يريد إجراء اختبارات للتحقق من عمل إحدى الصفحات. أوّل ما يخطر ببالنا هو فتح الصفحة والبحث عن عبارة معينة فيها، مما يعني أنَّ الصفحة متوافرة للزوار. يسهل كثيرًا فعل ذلك: <?php $I->amOnPage('/'); $I->see('Welcome'); ثم نستعمل الأمر الآتي لتشغيل اختبارات Codeception: $ php vendor/bin/codecept run سنلاحظ مباشرةً أنَّ شيئًا ما ليس صحيحًا، وسنرى من أوّل وهلة أنَّ رسالة الخطأ طويلة وغير واضحة، لكن عندما ننظر إليها عن قرب، فسنجد أنَّ معناها أصبح جليًا. لدينا اختبارٌ وحيدٌ وقد وَجَدَ خطأً: Acceptance Tests (1) Perform actions and see result (HelloWorldCept) Error ---------- 1) Failed to perform actions and see result in HelloWorldCept (tests/acceptance/HelloWorldCept .php) [GuzzleHttp\Exception\ConnectException] cURL error 6: Could not resolve host: localhost (see http://curl.haxx.se/libcurl/c/libcurl-errors.html) خلاصة الرسالة السابقة هي أنَّ الموقع في localhost غير متوافر. انظر إلى أوّل سطر من ملف الاختبار: 1. $I->amOnPage("/") لنفتح ملف tests/acceptance.suite.yml ونعدّل قيمة url: http://localhost/‎ إلى رابطٍ آخر تتوافر عليه الصفحة. يتوافر على جهازي المحلي خادومٌ يحتوي على الصفحة التي نريد اختبارها url: https://local.codeception-article.com/‎. شغِّل الاختبار مرةً أخرى، ويجب أن تظهر عندك النتيجة الآتية: Acceptance Tests (1) --------------------------------------------------------------------------------------- Perform actions and result (HelloWorldCept) Ok تهانينا! لقد نجح اختبارنا. تتوافر العديد من الدوال للاختبار بجانب الدالة amOnPage()‎، لكنني عرضتُها لسهولة استعمالها. يمكن تقسيم دوال الاختبار الموجودة في Codeception إلى المجموعات الآتية: دوال التفاعل مع الصفحة: fillField()‎ و selectOption()‎ و submitForm()‎ و click()‎. دوال التحقق من وجود أشياء معيّنة في الصفحة: see()‎ و dontSee()‎ و seeElement()‎ و seeInCurrentUrl()‎ و seeCheckboxIsChecked()‎ و seeInField()‎ و seeLink()‎. يمكنك إضافة لاحقة (suffix) إلى الدوال السابقة عندما تحتاج استعمالها دون أن توقف الاختبار إن لم يُعثَر على العنصر الذي تختبر وجوده. دوال التعامل مع الكعكات (cookies): setCookie()‎ و grabCookie()‎ و seeCookie()‎. التعليقات وشرح حالة الاختبار: amGoingTo()‎ و wantTo()‎ و expect()‎، استخدم هذه الدوال لكي تشرح ما الذي يفعله الاختبار، مما يذكرك بالهدف منه. فلو أردنا مثلًا أن نختبر صفحةً لاستعادة كلمة المرور عبر البريد الإلكتروني، فسنكتب ملفًا شبيهًا بالملف الآتي: <?php $I = new AcceptanceTester($scenario); $I->wantTo('Test forgotten password functionality'); $I->amOnPage('/forgotten') $I->see('Enter email'); $I->fillField('email', 'incorrect@email.com'); $I->click('Continue'); $I->expect('Reset password link not sent for incorrect email'); $I->see('Email is incorrect, try again'); $I->amGoingTo('Fill correct email and get link'); $I->see('Enter email'); $I->fillField('email', 'correct@email.com'); $I->click('Continue'); $I->expect('Reset password link sent for correct email'); $I->see('Please check your email for next instructions'); يبدو أنَّ الملف السابق يكفي لاختبار الصفحة، لكن ماذا لو كانت هنالك بعض الأقسام في الصفحة التي تُحمَّل عبر Ajax؟ كيف نستطيع أن نختبر تلك الصفحة؟ أجيبك أنَّ Codeception يستعمل مكتبة PhpBrowser المبنية على Symfony BrowserKit و Guzzle. أي لا تقلق، فالأمر سهلٌ وبسيط، ولن تحتاج إلا إلى استعمال curl لحل هذه المشكلة. يمكنك أيضًا استخدام Selenium واختبار الصفحات عبر المتصفحات الحقيقية. وصحيحٌ أنَّ ذلك أبطأ، إلا أنك ستتمكن من اختبار سكربتات JavaScript أيضًا. لكن أولًا عليك تثبيت إضافة Selenium، وتعديل ملف acceptance.suite.yml وإعادة بناء الصنف AcceptanceTester، ويمكنك بعد ذلك استخدام الدوال wait()‎ و waitForElement()‎؛ وستتمكن أيضًا من الحفاظ على وقتك ومواردك باستخدام الدالتين saveSessionSnapshot()‎ و loadSessionSnapshot()‎ اللتين تسمحان لك بحفظ حالة الجلسة الراهنة، وإجراء اختبارات جديدة على جلسات محفوظة مسبقًا، وقد تستفيد من هذا في بعض الحالات مثل اختبار عملية الاستيثاق من المستخدم. الخلاصة هي أننا نستطيع اختبار العديد من الوظائف بسهولة وسرعة وكفاءة. الاختبار الوظيفي لننتقل الآن إلى إجراء اختبارات وظيفية على تطبيقنا: $ php vendor/bin/codecept generate:cept functional HelloWorld ومحتوى الملف: <?php $I = new FunctionalTester($scenario); $I->amOnPage('/'); $I->see('Welcome'); انتظر قليلًا، ماذا يحدث! لا يوجد خطأ في الشيفرة السابقة، حيث تُكتَب الاختبارات الوظيفية بنفس طريقة كتابة اختبارات التكامل، الفرق بينهما هو أنَّ الاختبارات الوظيفية تتفاعل مباشرةً مع تطبيقك، مما يعني أنَّك لن تحتاج إلى خادوم ويب لتشغيل اختبار وظيفي، وستستطيع اختبار أجزاء مختلفة من تطبيقك. وصحيحٌ أنَّه لا يتوافر دعمٌ لجميع إطارات العمل، لكن قائمة الإطارات المدعومة كبيرة (Symfony، و Silex، و Phalcon، و Yii، و Zend Framework، و Lumen، و Laravel) ويجب أن تكون كافيةً لأغلبية الحالات ولمعظم المطورين. رجاءً راجع توثيق Codeception للحصول على قائمة بجميع الدوال المتوافرة وكيفية تفعيلها في ملف functional.suite.yml. قبل أن ننتقل إلى اختبارات الوحدات، فدعني أنحرف قليلًا عن الموضوع وأحدثك قليلًا عن شيءٍ ربما لاحظتَه عند إنشاء الاختبارات: $ php vendor/bin/codecept generate: cept acceptance HelloWorld لاحظ الكلمة cept، واعلم أنَّ ما سبق ليس الطريقة الوحيدة لإنشاء الاختبارات، فهنالك أيضًا «اختبارات cest»، والفرق بينهما هو أنَّك تستطيع هيكلة عدِّة حالات وسيناروهات في نفس الصنف: $ php vendor/bin/codecept generate:cest acceptance HelloWorld <?php class HelloWorldCest { public function _before(AcceptanceTester $I) { $I->amOnPage('/forgotten') } public function _after(AcceptanceTester $I) { } // tests public function testEmailField(AcceptanceTester $I) { $I->see('Enter email'); } public function testIncorrectEmail(AcceptanceTester $I) { $I->fillField('email', 'incorrect@email.com'); $I->click('Continue'); $I->see('Email is incorrect, try again'); } public function testCorrectEmail(AcceptanceTester $I) { $I->fillField('email', 'correct@email.com'); $I->click('Continue'); $I->see('Please check your email for next instructions'); } } ستُشغَّل الدالتان ‎_before()‎ و ‎_after()‎ قبل وبعد كل اختبار. وستُمرَّر نسخةٌ من الصنف AcceptanceTester إلى كل اختبار، لذا يمكنك استخدامه بنفس الآلية المتبعة في اختبارات cest. قد يكون هذا النوع من الاختبارات مفيدًا في بعض الأحيان، لذا من المفيد تعلمه ومعرفة وجوده. اختبارات الوحدات أخيرًا: اختبارات الوحدات. بُني Codeception على PHPUnit، أي أنَّك تستطيع استخدام الاختبارات المكتوبة لمكتبة PHPUnit، وذلك باستخدام الأمر الآتي: $ php vendor/bin/codecept generate:phpunit unit HelloWorld أو يمكنك ببساطة أن «ترث» (inherit) الاختبارات في ‎\PHPUnit_Framework_TestCase. لكن إن أردتَ شيئًا إضافيًا، فيمكنك تجربة اختبارات الوحدات التي يوفرها Codeception: $ php vendor/bin/codecept generate:test unit HelloWorld <?php class HelloWorldTest extends \Codeception\TestCase\Test { /** * @var \UnitTester */ protected $tester; protected function _before() { } protected function _after() { } // tests public function testUserSave() { $user = User::find(1); $user->setEmail('correct@email.com'); $user->save(); $user = User::find(1); $this->assertEquals('correct@email.com', $user->getEmail()); } } لا شيء يختلف عمّا عهدتَه من قبل، فالدالتان ‎_before()‎ و ‎_after()‎ هما بديلتا setUp()‎ و tearDown()‎، وستعملان قبل وبعد كل اختبار. الميزة الأساسية لهذا الاختبار هي القدرة على توسعة عملية الاختبار بتضمين وحدات (modules) التي يمكن تفعيلها في ملف unit.suite.yml: الوصول إلى memcache وقواعد البيانات لتتبع التغيرات (قواعد MySQL و SQLite و PostgreSQL و MongoDB مدعومة). اختبار تطبيقات REST/SOAP. Queues كل وحدة (module) لها ميزاتها، لذا من الأفضل أن تنظر إلى التوثيق وتجمع المعلومات الضرورية عنها قبل الانتقال إلى كتابة اختبارات تستعملها. يمكنك أيضًا استعمال حزمة Codeception/Specify (والتي يجب إضافتها إلى ملف composer.json) وتكتب وصفًا كالآتي: <?php class HelloWorldTest extends \Codeception\TestCase\Test { use \Codeception\Specify; private $user; protected function _before() { $this->user = User::find(1); } public function testUserEmailSave() { $this->specify("email can be stored", function() { $this->user->setEmail('correct@email.com'); $this->user->save(); $user = User::find(1); $this->assertEquals('correct@email.com', $user->getEmail()); }); } } شيفرة PHP الموجودة ضمن الدوال المغلقة (closure functions) السابقة معزولةٌ، لذا لن تؤثر التعديلات داخلها على بقية شيفراتك. ستساعد عبارات الشرح بجعل الغاية من الاختبار واضحةً وتسهيل التعرف على الاختبارات التي فشلت. إضافةً إلى ما سبق، يمكنك استعمال الحزمة Codeception\Verify لكتابة اختبارات بشيفرة شبيهة بأسلوب BDD: <?php public function testUserEmailSave() { verify($map->getEmail())->equals('correct@email.com'); } ويمكنك بالطبع استعمال stub: <?php public function testUserEmailSave() { $user = Stub::make('User', ['getEmail' => 'correct@email.com']); $this->assertEquals('correct@email.com', $user->getEmail()); } الخلاصة: يساعد Codeception على توفير الوقت والجهد ما الذي تتوقع الحصول عليه من Codeception؟ من هم الأشخاص المناسبون لاستعماله؟ برأيي الشخصي، Codeception مناسب لجميع أنواع الفرق: الكبيرة والصغيرة، والمبتدئين والمحترفين، والذين يستعملون أطر عمل والذين يكتبون برمجياتهم من الصفر، أي أنَّ Codeception صالحٌ لكل زمان ومكان (تقريبًا). Codeception هو إطار عمل ناضج وموثّق جيدًا ويمكن توسعته باستعمال إضافات. وهو حديثٌ، ومبنيٌ على المكتبة الشهيرة PHPUnit، مما يطمئن المطورين الذين لا يريدون تجربة الكثير من المكتبات قبل الاستقرار. أداءُ هذه المكتبة جيدٌ، وهذا يعني أنها سريعة ولا تحتاج وقتًا ولا جهدًا كثيرًا، ومن السهل تعلمها، والتوثيق الرائع يجعل عملية التعلم تمر دون مشاكل. من السهل جدًا تثبيت وضبط Codeception، مع أنه يحتوي على الكثير من الميزات المتقدمة. وصحيحٌ أنَّ أغلبية المستخدمين لا يحتاجون جميع (أو حتى أغلب) الميزات الموجودة فيه، إلا أنَّ ذلك يعتمد على ما تشاء فعله معه. يمكنك البدء بالأساسيات، ثم ستبدأ بالتعامل مع الميزات الإضافية عاجلًا أو آجلًا. ترجمة -وبتصرّف- للمقال Jumpstart Your PHP Testing with Codeception لصاحبه Vasily Koval
    1 نقطة
  2. درسك هدية بالنسبة لي والله انت معلم شكرا لك على المعلومة المفيدة و الجيدة شكرا لك على هذه المعلومات القيمة.. مجهود رائع حقيقة أعجبني موضوعك وأشكركم على المشاركة معنا مع أطيب التحيات واصل.
    1 نقطة
  3. عندما نكتب برنامجًا طويلًا جدًا، فإن الشيفرة ستوزَّع في عددٍ من الملفات والأصناف (classes) والدوال (functions)؛ الدوال هي مجموعة من التعليمات التي تنجز مُهمِّة معيّنة وهدفها ألا تكرر الشيفرات التي تكتبها؛ فمثلًا في نظام للاستيثاق، يكون هنالك دوال لتسجيل الدخول (login) والتسجيل (register) وتسجيل الخروج (logout). أبسط أشكال الدوال إن الشكل العام لأبسط دالة هو: <?php function function_name() { // الشيفرة } ?> وكما في المتغيرات، تستطيع إسناد أي اسم إلى الدالة (أعطينا الدالة في المثال السابق الاسم function_name). تُكتَب الشيفرة التي ستنفذها الدالة عندما يتم استدعاؤها بين أقواس معقوفة ({})؛ نستطيع استدعاء الدالة عبر كتابة اسمها ويليه أقواس عادية () كما في المثال الآتي: <?php // يمكنك أن تستدعي الدالة هنا قبل تعريفها // تعريف دالة ذات الاسم say_hello function say_hello() { // كل ما تفعله هذه الدالة هو طباعة hello echo "hello"; } // استدعاء الدالة say_hello(); ?> الدوال ذات الوسائط يمكننا تمرير المعلومات الإضافية (مثل اسم المستخدم وكلمة المرور) إلى الدوال باستخدام الوسائط (arguments)، وعلينا تعريف المعاملات (parameters). ملاحظة: الوسائط هي البيانات التي نمررها إلى الدالة عندما نستدعيها، أما المعاملات فهي المتغيرات التي نُعرِّفها عندما نكتب الشيفرة الخاصة بالدالة. يمكننا أن نعتبر أن المعاملات هي حاويات والوسائط هي البيانات التي نضعها في تلك الحاويات. <?php // دالة تسجيل الدخول ذات وسيطين function login($user, $pass) { // تطبع هذه الدالة اسم المستخدم وكلمة المرور echo "hello, username is $user and password is $pass"; } // استدعاء الدالة login("user1","UsEr!p@$$W0rD"); // استدعاء الدالة مرةً أخرى login("user2","simplepassword"); ?> المعاملات ذوات القيم الافتراضية يمكننا أن نعطي قيمًا افتراضية للمعاملات لكي يمكن تجاوز تحديد قيمتها عند استدعاء الدالة. <?php // دالة تسجيل الدخول ذات ثلاثة وسائط function login($user, $pass, $active = "not active") { // تعرِض هذه الدالة اسم المستخدم وكلمة مروره وحالته echo "hello, username is $user and password is $pass and user is $active"; } // استدعاء الدالة login('user1','UsEr!p@$$W0rD'); // استدعاء الدالة مرةً أخرى login('user2','simplepassword', 'active'); ?> ملاحظة: إن أردت ألّا تُحدِّد قيمةً لوسيطٍ ما عند استدعاء الدالة، فيجب أن يكون المعامل الموافق لذاك الوسيط في آخر القائمة كما في المثال السابق. ويملك المعامل افتراضيًا القيمة "null". الدوال ذات المعاملات متغيرة العدد يمكن أن تملك الدوال عددًا متغيرًا من المعاملات؛ وفي الواقع، تستطيع تمرير إي عدد من الوسائط إلى دالة؛ استعمل الدوال المُضمَّنة في PHP الآتية للوصول إلى تلك الوسائط: الدالة func_get_args()‎: تُعيد مصفوفة بجميع الوسائط المُمرَّرة الدالة func_num_args()‎: تُعيد العدد الإجمالي للوسائط المُمرَّرة. الدالة func_get_arg(argument_number)‎: تُعيد المتغير ذو الرقم argument_number سنظهِر -في المثال الآتي- مجموع الأرقام المُمرَّرة إلى الدالة كوسائط بالإضافة إلى عرضها. <?php function sum() { // سنستعمل func_get_args() للحصول على كل المعاملات على شكل مصفوفة $ary = func_get_args(); print_r($ary); echo "<br>"; $sum = 0; // سنستعمل func_num_args للحصول على العدد الكلي للمعاملات for($i = 0; $i < func_num_args(); $i++) { // سنستعمل func_get_arg(index) للحصول على قيمة معامل معيّن echo func_get_arg($i).'<br>'; $sum+= func_get_arg($i); } echo "sum is $sum <br><br>"; } sum(1,2,3,4); sum(23,2343,54,2,1,6); ?> ناتج تنفيذ السكربت السابق هو: Array ( [0] => 1 [1] => 2 [2] => 3 [3] => 4 ) 1 2 3 4 sum is 10 Array ( [0] => 23 [1] => 2343 [2] => 54 [3] => 2 [4] => 1 [5] => 6 ) 23 2343 54 2 1 6 sum is 2429 إعادة القيم من الدوال لاحظ أننا في المثال السابق طبعنا السلسلة النصية مباشرةً، لكن ماذا لو أردنا أن نجعل الدالة تُعيد قيمةً ما؟ نستعمل العبارة البرمجية return لإعادة قيمة من الدالة، وتُسبِّب هذه العبارة بإنهاء تنفيذ الدالة مباشرةً وإعادة القيمة إلى مكان استدعاء الدالة، لنرى مثالًا عن دالة تُعيد مربَّع العدد المُمرَّر إليها: <?php function square ($num) { return $num * $num; } // الناتج هو 16 echo square (4); ?> لاحظ أنك لا تستطيع إعادة أكثر من قيمة من الدالة، لكن يمكنك إعادة مصفوفة التي تؤدي نفس الدور تقريبًا. <?php function powers ($num) { return array ($num, $num * $num, $num * $num * $num); } // الناتج هو: Array ( [0] => 4 [1] => 16 [2] => 64 ) print_r(powers (4)); ?> مجالات تعريف الدوال تستطيع أن تستدعي الدوال المُعرَّفة في الأمثلة السابقة قبل مكان تعريفها، لأن مجالها (scope) هو المجال العام، يجدر بالذكر أنَّك تستطيع تعريف الدوال داخل جملة شرطية (if) لكن لا يمكنك استدعاؤها إن لم يتحقق الشرط كما في المثال الآتي: <?php $str = 'create the function'; global_function(); // لا يمكننا استدعاء الدالة not_global هاهنا، لأن المفسر لا يعتبرها موجودةً إن لم تتحقق الجملة الشرطية الآتية if ($str == 'create the function') { function not_global() { echo 'I don\'t exist until program execution reaches me'; } } // نستطيع الآن استدعاء الدالة not_global بعد اختبار أن السلسلة $str مساوية للقيمة اعلاه، لتجنب إظهار خطأ if ($str == 'create the function') not_global(); function global_function() { echo 'I exist immediately upon program start'; } ?> الأمر سيان لآلية تعريف دالة داخل دالة أخرى: <?php function global_function() { function not_global() { echo 'I don\'t exist until global_function() is called'; } } // لا يمكننا استدعاء not_global هنا، إذ علينا استدعاء global_function أولًا global_function(); // نستطيع الآن استدعاء الدالة not_global، لأن استدعاء global_function قد جعلها متاحةً للمفسر not_global(); ?> المتغيرات في الدوال مجال المتغيرات (variable scope) هو "المجال" الذي يبقى فيه المتغير مُعرَّفًا، أي بكلامٍ آخر، المتغيرات المُعرَّفة داخل الدوال لا يمكن الوصول إليها من خارج تلك الدوال؛ أما المتغيرات المُعرَّفة في المجال العام (global scope) يمكن الوصول إليها من أي جزء من البرنامج في المجال العام؛ ربما أربكك الشرح السابق لكن انظر إلى هذا المثال للتوضيح: <?php // المتغير $a في المجال العام $a = 1; function test() { echo $a; // لا يمكن الوصول إلى المتغير $a لأنه في المجال العام } // لن يظهر أي شيء ﻷن المتغير $a ليس ضمن مجال الدالة test(); // سيظهر الرقم 1، لأن المجال هو العام echo $a; ?> لن تظهر مخرجات عند استدعاء الدالة test()‎ لأن الدالة echo داخلها تُشير إلى نسخة محلية من المتغير ‎$a التي لم تُسنَد لها قيمة في ذاك المجال. يمكن الوصول إلى المتغيرات في المجال العام من داخل الدوال باستخدام الكلمة المحجوزة global كما يلي: <?php $a = 1; $b = 2; function sum (){ // أصبح بإمكاننا الوصول إلى المتغيرين في مجال الدالة الخاص، وتعديل قيمتهما مباشرةً global $a, $b; $b = $a + $b; } sum(); echo $b; ?> نوعٌ أخيرٌ هو المتغيرات الثابتة (static variables) التي يُسمَح بوجودها في مجال الدوال الخاص فقط، لكنها لا تفقد قيمتها عند انتهاء تنفيذ الدالة، انظر إلى المثال الآتي لتوضيح الأمور: <?php function test() { $a = 0; echo $a; $a++; } ?> الدالة السابقة عديمة الفائدة لأنها في كل مرة تُستدعى فيها ستضبط قيمة المتغير ‎$a إلى 0، ثم ستُظهِر قيمة ذاك المتغير (التي هي صفر)، وأخيرًا لن نستفيد من زيادة قيمة المتغير (‎$a++‎) لانتهاء تنفيذ الدالة ولن يعود المتغير ‎$a موجودًا. أما لو عرَّفنا المتغير ‎$a على أنه ثابت، فلن يفقد قيمته بعد انتهاء تنفيذ الدالة: <?php function test() { static $a = 0; echo $a; $a++; } ?> ستتم تهيئة المتغير ‎$a في أول مرة تُستدعى فيها الدالة، وستُطبَع قيمة المتغير وستزداد قيمته في كل مرة تستدعى فيها الدالة مرةً أخرى. <?php function test() { static $a = 0; echo $a; $a++; } //الناتج 0 test(); //الناتج 1 test(); //الناتج 2 test(); ?> ملاحظة: يجب إسناد قيم بسيطة إلى المتغيرات الثابتة عند تعريفها، إذ لا يجوز استعمال التعابير الرياضية أو إسناد القيم المُعادة من الدوال إليها. المعاملات المرجعية رأينا كيف أنَّ جميع الدوال السابقة تعيد قيمة ما بناءً على العمليات التي تُجرى فيها، لكنها لا تستطيع تعديل قيم الوسائط المُمرَّرة إليها، لكن "التمرير بالمرجعية" (pass by reference) يسمح للدوال بتعديل قيم الوسائط مباشرةً، لنأخذ مثالًا بسيطًا يوضِّح هذا الأمر: <?php function test(&$var) { $var++; // لاحظ عدم استعمال عبارة return هنا } $a = 5; test($a); echo $a; // الناتج هو 6 ?> الاختلاف الوحيد الذي يجعل الوسائط تُمرَّر بمرجعيتها هو وضع محرف «&» قبل اسم الوسيط عند تعريف الدالة. الدوال المجهولة الدوال المجهولة (anonymous functions) التي تُعرَف أيضًا بالمصطلح "closures" تسمح بإنشاء دالة ليس لها اسم محدد، وإنما تُسند مباشرةً إلى متغير مَثَلُها كَمَثَلِ أيّةِ عملية إسنادٍ أخرى، وتنتهي عملية الإسناد أيضًا بفاصلة منقوطة؛ هذا مثالٌ عنها: <?php $square = function ($num) { echo $num * $num; }; $square(2); // الناتج 4 $square(15); // الناتج 225 ?> نستطيع أن نُمرِّر إلى الدوال المجهولة أي متغير موجود في مجال المتغيرات الأعلى منها وذلك باستخدام الكلمة المحجوزة use، تأمّل في المثال الآتي وفي تعليقاته: <?php $message = 'hello'; // لم نستعمل الكلمة المفتاحية use هنا $example = function () { echo $message; }; $example(); // لن تَظهَر أيّة قيمة (أو بالتحديد، سيظهر خطأ Notice ﻷن المتغير غير مُعرَّف) // تمرير المتغير $message $example = function () use ($message) { echo $message; }; $example(); // الناتج: hello // القيمة المُمرّرة تؤخذ قبل تعريف الدالة، وليس قبل استدعائها $message = 'world'; $example(); // الناتج: hello // إعادة قيمة المتغير إلى قيمته الأصلية $message = 'hello'; // الوراثة بالمرجعية (inherit by-reference) $example = function () use (&$message) { echo $message; }; $example(); // الناتج: hello // إذا تغيرت قيمة المتغير الآن، فستتأثر الدالة المجهولة بها $message = 'world'; $example(); // الناتج: world // استعمال الوسائط العادية $example = function ($arg) use ($message) { echo $arg . ' ' . $message; }; $example("hello"); // الناتج: hello world ?> تمرين اكتب دالةً تقبل وسيطين أولهما هو طول المستطيل والآخر هو عرض المستطيل، وستعيد هذه الدالة أربع قيم تُمثِّل إحداثيات نقاط التقاء أضلاعه على فرض أنَّ مركزه يقع على مبدأ الإحداثيات. المصادر مقال Functions in php لصاحبه Harish Kumar. مقالتي Functions و Closures لصاحبهما Dayle Rees. صفحات Functions و Anonymous functions و User-defined functions في دليل php وغيرها.
    1 نقطة
  4. ملخص جيد مشكور يا اخى الفاضل على درسك الرائع.. سأقوم بنسخه وإني متعطش لمثل هذه المعلومات انه لدرس رائع و متميز في ايصال المعلومة بشكل سريع.
    1 نقطة
  5. سنكمل الآن ما تعلمناه في الدرس السابق عن السلاسل النصية. وقد كان محتوى الدرس الأول كالآتي: إنشاء والوصول إلى السلاسل النصية باستخدام $ و {}، واستخدام الدالة strlen()‎. البحث في السلاسل النصية باستعمال الدوال: strstr()‎ strpos()‎ و strrpos()‎ substr_count()‎ strpbrk()‎ الاستبدال في السلاسل النصية باستخدام الدوال: str_replace()‎ ()substr_replace ()strtr strtr()‎ التعامل مع حالات الحروف الكبيرة (uppercase) والصغيرة (lowercase) باستخدام الدوال: strtolower()‎ strtoupper()‎ ucfirst()‎ lcfirst()‎ ucword()‎ النسخ غير الحساسة لحالة الأحرف لجميع الدوال السابقة. أما هذا الدرس فسيحتوي على ما يلي: تنسيق السلاسل النصية باستخدام printf()‎، بما في ذلك تعيين دقة الأرقام العشرية. إزالة الفراغات (trimming) من أطراف السلاسل النصية باستعمال الدوال: trim()‎ ltrim()‎ rtrim()‎ إضافة حواشي (paddings) للنصوص باستعمال الدوال: str_pad()‎ STR_PAD_RIGHT STR_PAD_LEFT STR_PAD_BOTH التفاف (wrapping) النصوص عبر استعمال الدالة wordwrap()‎. تنسيق الأرقام باستخدام الدالة number_format()‎. الوقت والتاريخ. تنسيق السلاسل النصية الدالة printf()‎ الدالة printf()‎ هي أداةٌ قويةٌ تمكِّنك من تنسيق السلاسل النصية بطرقٍ مختلفة، تأخذ printf()‎ وسيطًا يُسمى سلسلة التنسيق (format string) يُتبَع عادةً بوسيطٍ اختياري أو أكثر يحتوي على السلسلة أو السلاسل التي ستوضع في السلسلة السابقة، ثم ستطبع هذه الدالة النتيجة النهائية. سلسلة التنسيق تحتوي على نصٍ عادي وفيه مُحدِّدات التنسيق (conversion specifications)، يتطلب وجود كل محدد تنسيق وسيطًا إضافيًا يُمرَّر إلى printf()‎، ومهمته هي تنسيق ذاك الوسيط ووضعه في سلسلة التنسيق، ثم بعد ذلك ستُعرَض السلسلة النهائية المُنسَّقة؛ تبدأ محددات التنسيق دومًا بإشارة النسبة المئوية (%)، ربما يبدو الأمر معقدًا للوهلة الأولى، لكن مثالًا بسيطًا كهذا سيجعل إيصال الفكرة أمرًا هينًا: <?php // الناتج: "Pi rounded to a whole number is: 3" printf( "Pi rounded to a whole number is: %d", M_PI ); ?> إن عبارة "Pi rounded to a whole number is: %d" هي سلسلة التنسيق، و "%d" ضمن السلسلة السابقة هي محدد للتنسيق، وفي هذه الحالة، يُخبِر هذه المحدد الدالة printf()‎ أن تقرأ الوسيط الإضافي وتضعه -بعد تنسيقه كعدد صحيح- في سلسلة التنسيق؛ الوسيط الإضافي هو الثابت M_PI الموجود في لغة PHP، التي يُمثِّل القيمة التقريبية للعدد π بعدد معيّن من المنازل العشرية (14 منزلة افتراضيًا)؛ أي أنَّ النتيجة النهائية لاستدعاء الدالة السابقة هي طباعة سلسلة التنسيق مع استبدال "%d" بقيمة الثابت π مُقرَّبًا إلى أقرب عدد صحيح. المزيد من المُحدِّدات: b: معاملة الوسيط كعدد صحيح (integer) وتنسيقه كعدد ثنائي. c: معاملة الوسيط كعدد صحيح وتنسيقه كمحرف بنظام ASCII الذي يحمل نفس القيمة العددية. d: معاملة الوسيط كعدد صحيح وتنسيقه كعدد عشري مع إشارة (signed). e: تنسيق الوسيط بالطريقة العلمية (مثلًا، 3.45e+2). f: تنسيق الوسيط كعدد ذو فاصلة عائمة (floating point)، آخذًا بالحسبان إعدادات «المحليّة» (locale) الحالية (على سبيل المثال، تستعمل بعض الدول الأوروبية الفاصلة كعلامة تفصل الأرقام الصحيحة عن الأرقام العشرية عوضًا عن النقطة؛ أي 3,14 بدلًا من 3.14). F: تنسيق الوسيط كعدد ذو فاصلة عائمة بغض النظر عن إعدادات المحليّة. o: معاملة الوسيط كعدد صحيح وتنسيقه كعدد بالنظامي الثماني. s: تنسيق الوسيط كسلسلة نصيّة. u: معاملة الوسيط كعدد صحيح وتنسيقه كعدد عشري دون إشارة (unsigned). x: معاملة الوسيط كعدد صحيح وتنسيقه كعدد بالنظام الست عشري بأحرفٍ ذات الحالة الصغيرة (lowercase). X: معاملة الوسيط كعدد صحيح وتنسيقه كعدد بالنظام الست عشري بأحرفٍ ذات الحالة الكبيرة (uppercase). %: إظهار إشارة النسبة المئوية (%)، لا يتطلب هذا المُحدِّد وجود وسيط إضافي. إضافة حواشي إلى المخرجات يمكنك إضافة محارف إلى يسار (افتراضيًا) أو إلى يمين الوسيط الذي يتم تنسيقه كي يُصبِح بعرضٍ معيّن، وهذا مفيدٌ إن أردت أن تُضيف أصفارًا تسبِق الأعداد، أو أن تحاذي عدِّة سلاسل نصية أفقيًا عبر إضافة فراغات على جوانبها. <?php // الناتج‏‎: "000123" printf( "%06d<br/>", 123 ); // الناتج‏‎: "004567" printf( "%06d<br/>", 4567 ); // الناتج‏‎: "123456" printf( "%06d<br/>", 123456 ); ?> دقة الأرقام عندما تُظهِر الأعداد ذات الفاصلة العائمة باستخدام المحدِّد f أو F، يمكنك استعمال مُحدِّد لدقة الأرقام لتعيين عدد المنازل العشرية التي سيُقرَّب (أو يدوَّر) إليها الرقم. لإضافة مُحدِّد دقة الأرقام، أضف نقطة (.) يلحقها عدد المنازل العشرية التي ستستخدم، قبل مُحدِّد النوع؛ انظر إلى المثال الآتي للتوضيح: <?php // الناتج‏‎: "123.456700" (الدقة الافتراضية) printf( "%f<br />", 123.4567 ); //الناتج ‏‎: "123.46" printf("%.2f<br />", 123.4567 ); // الناتج‏‎: "123" printf("%.0f<br />", 123.4567 ); // الناتج‏‎: "123.4567000000" printf("%.10f<br />", 123.4567 ); ?> يمكنك استخدام مُحدِّد الحاشية مع مُحدِّد الدقة، في حال أردت أن يكون طول الرقم معينًا (بما في ذلك الأرقام بعد الفاصلة العشرية، والفاصلة نفسها أيضًا): <?php // الناتج‏‎: "123.46" printf( "%.2f<br />", 123.4567 ); // الناتج‏‎: "000000123.46" printf( "%012.2f<br />", 123.4567 ); // الناتج‏‎: " 123.4567" printf( "%12.4f<br />", 123.4567 ); ?> إزالة الفراغات من أطراف السلاسل النصية قد لا ترغب في بعض الأحيان بوجود أيّة فراغات قبل أو بعد السلسلة النصية، وفي هذه الحالة نستعمل هذه الدوال: trim()‎: إزالة الفراغات (white-space) من بداية ونهاية السلسلة النصية. ltrim()‎: إزالة الفراغات من بداية السلسلة النصية فقط. rtrim()‎: إزالة الفراغات من نهاية السلسلة النصية فقط. انظر إلى ناتج المثال الآتي للتوضيح: <?php echo trim(" hsoub "); echo ltrim(" hsoub "); echo rtrim(" hsoub "); ?> إضافة حواشي إلى النصوص لقد رأينا سابقًا كيف يمكننا استخدام الدالة printf()‎ لإضافة حواشي إلى بداية أو نهاية سلسلة نصيّة؛ لكن لغة PHP توفِّر دالةً مخصصةً لهذا الأمر اسمها str_pad()‎، وهي أكثر مرونةً من printf()‎ وأسهل استخدامًا. لاستعمال الدالة str_pad()‎، مرِّر السلسلة التي ستتم إضافة الحواشي إليها، وعرض السلسلة النهائي، وستعيد الدالة السلسلة وقد تمت إضافة فراغات إلى يمينها (افتراضيًا): <?php echo '<pre>'; echo str_pad( "Hello, world!", 20 ); // الناتج‏‎: "Hello, world! " echo '</pre>'; ?> ولإضافة محارف أخرى غير الفراغ كحاشية، فمرِّر سلسلةً نصيةً كوسيطٍ ثالثٍ اختياري، لاحظ أنَّك تستطيع استخدام محرف وحيد أو أكثر من محرف؛ وفي الحالة الأخيرة، ستُكرَّر السلسلة النصية حسب العرض المُحدَّد: <?php // الناتج‏‎: "Hello, world!*******" echo str_pad( "Hello, world!", 20, "*" ) . "\n"; // الناتج‏‎: "Hello, world!1231231" echo str_pad( "Hello, world!", 20, "123" ) . "\n"; ?> يمكنك جعل الدالة str_pad()‎ تضع الحاشية على يسار السلسلة النصية، أو على يمنيها ويسارها معًا؛ وذلك بتمرير وسيط ثالث اختياري يحتوي على ثوابت الدالة المذكورين في الجدول الآتي: STR_PAD_RIGHT: إضافة الحاشية على اليمين (الحالة الافتراضية)، مما يحاذي السلسلة النصيّة إلى اليسار. STR_PAD_LEFT: إضافة الحاشية على اليسار، مما يحاذي السلسلة النصيّة إلى اليمين. STR_PAD_BOTH: إضافة الحاشية على الطرفين الأيمن والأيسر معًا، مما يؤدي إلى توسيط السلسلة النصية ما أمكن. مثال: (لاحظ وجود 3 محارف للحاشية على اليسار، و4 على اليمين؛ إذ لا يمكن توسيطها تمامًا): <?php // الناتج‏‎: "***Hello, world!****" echo str_pad( "Hello, world!", 20, "*", STR_PAD_BOTH ) . "\n"; ?> التفاف النصوص أحيانًا يكون عندك نصٌ طويلٌ مثل رسائل البريد الإلكتروني أو المقالات، وربما تريد أن تُقسَّم الأسطر بعرضٍ مختلف. تفعل الدالة wordwrap()‎ هذا الأمر؛ يمكنك تحديد عدد المحارف في السطر عبر هذه الدالة، انظر إلى هذا المثال أولًا: <?php $myString = "this is my string which is very long. it is containing five lines and a number of white spaces"; echo wordwrap ($myString); echo "<br><br><br>"; echo wordwrap ($myString, 40); echo "<br><br><br>"; echo wordwrap ($myString, 40, "<br />"); ?> لاحظ النتيجة بنفسك بفتح مصدر صفحة الويب ورؤية النتيجة لمختلف الجمل بقيمٍ مختلفة للوسيط الثاني (غير 40، مثل 10، أو 15، أو 20 ...إلخ.). تنسيق الأعداد تُستعمَل الدالة number_format()‎ لتنسيق الأعداد، وتستقبل وسيطًا أو وسيطين أو أربعة وسائط. أول وسيط هو العدد الذي سيُنسَّق الوسيط الثاني هو عدد المنازل العشرية الوسيط الثالث هو المحرف الذي سيفصل بين الأعداد الصحيحة والأرقام العشرية أما رابع وسيط، فيُحدِّد المحرف الذي سيفصل بين الآلاف في الأعداد الصحيحة يوضَّح ما سبق بالمثال الآتي: <?php $myNumber = 12344555.3453; // الناتج‏:‎ 1,23,44,555.3453 echo number_format($myNumber); echo "<br>"; // الناتج‏:‎ 1,23,44,555.34 echo number_format($myNumber,2); echo "<br>"; // الناتج‏:‎ 1 23 44 555,3453 echo number_format($myNumber,2,',',' '); echo "<br>"; ?> الوقت والتاريخ يلزم الحصول على الوقت والتاريخ وعرضه بطريقة مناسبة كثيرًا في تطوير الويب، ولهذا توفِّر PHP الأدوات اللازمة لذلك. أهم تلك الأدوات هي الدالة date()‎ التي تقبل سلسلةً نصيةً تُحدِّد تنسيق المخرجات، وتتألف من محارف التنسيق الآتية: d: يعيد رقم اليوم من الشهر، وتتراوح قيمته من 01 إلى 31. استخدام المحرف j للحصول على رقم اليوم دون 0 بادئة. m: يعيد رقم الشهر، وتتراوح قيمته من 01 إلى 12. استخدام المحرف n للحصول على رقم الشهر دون 0 بادئة. w: الحصول على رقم اليوم من الأسبوع، وتتراوح قيمته بين 0 الذي يشير إلى يوم الأحد، و6 ليوم السبت. h: الحصول على الساعة الحالية بنظام 12 ساعة. استخدم g للحصول على الساعة بنظام 24 دون 0 بادئة. استخدام a للحصول على am أو pm، و A للحصول على AM أو PM. H: الحصول على الساعة الحالية لكن بنظام 24 ساعة. استخدم G للحصول على الساعة بنظام 24 دون 0 بادئة. i: الحصول على الدقائق. s: الحصول على الثواني. Y: الحصول على السنة على هيئة أربعة أرقام. ويمكن تمرير وسيطٍ اختياري هو بصمة الوقت (timestamp) لكي تُعيد الدالة date()‎ قيمة التاريخ والوقت لها، لكن إن لم تُحدِّد بصمة الوقت، فستؤخذ القيمة من ناتج الدالة time()‎ التي تُعيد بصمة الوقت مقاسةً بالثواني منذ بداية وقت يونكس (Unix Time) (أي منتصف ليلة رأس السنة عام 1970). <?php // الناتج‎: 12:31:55 echo date('H:i:s'); // الناتج‎: 2015/12/23 echo date('Y/m/d'); ?> ملاحظة: يجدر بالذكر أنَّ الدالة mktime()‎ تنُشِئ بصمة الوقت لتاريخ معيّن كي تستعملها مع الدالة date، شكلها العام هو الآتي: mktime($hour, $minute, $second, $month, $day, $year); حيث أول وسيط هو الساعة، والثاني هو الدقيقة، والثالث هو الثانية، والرابع هو الشهر، والخامس هو اليوم من الشهر، والسادس هو السنة؛ مثالٌ عن استعمالها: <?php // الناتج هو مثلًا‏‎: 1450872238 $current_time = time(); echo $current_time; // ناتج بصمة الوقت هو‎: 1030134920 $past_time = mktime(22, 35, 20, 8, 23, 2002); echo $past_time; // الناتج هو‎: 12-23-2015 13:03 // يمكن أن نحذف الوسيط الثاني، لأن الدالة date ستعتمد الوقت الحالي المُعادة من الدالة time افتراضيًا echo 'current date is: ' . date ('m-d-Y H:i' , $current_time); // الناتج هو‎: 08-23-2002 22:35 // يمكن أن نحذف الوسيط الثاني، لأن الدالة date ستعتمد الوقت الحالي المُعادة من الدالة time افتراضيًا echo 'a date in the past: ' . date ('m-d-Y H:i' , $past_time); ?> تمرين اكتب برنامجًا يأخذ تاريخ ميلاد المستخدم ثم يُظهِر عمره بالسنوات والأشهر والأيام؛ مثلًا: 35 سنة، و 4 أشهر، و23 يومًا. المصادر مقال Strings in PHP part-2 لصاحبه Harish Kumar. صفحة sprintf، و date في دليل PHP وغيرها.
    1 نقطة
  6. شكرا على التميز والابداع في العرض والاخراج لهذا الدرس التطبيقي
    1 نقطة
  7. ما أهم شيء يجب أن يكون لدى المبرمج حتى يكون مبرمج محترف؟
    1 نقطة
  8. لن أضيف الشيء الكثير عن ما تفضل به hassenـ حيث فيما يتعلق بـ TeamViewer أضع رابط الفيديو الذي يوضح كيفية القيام بالحكم بهاتف أندرويد من خلال هاتف آخر عن طريق برنامج Teamviewer: يوجد أيضا تطبيق RemoDroid الذي يتيح نفس المهمة-التحكم في هاتف أندرويد-، و هذا توضيح لكيفية ذلك: موقع Join me : يعتبر من بين أفضل متحكمات أندرويد من خلال هاتف أندرويد آخر. تطبيق ScreenShare:
    1 نقطة
  9. شكرًا لك. نعم يمكنك الإنتقال إلى أندرويد ستديو خطوة بخطوة مع هذه السلسلة من الدروس، وتهدف دروس جافا لشرح المفاهيم الأساسية للتعامل مع لغات البرمجة وشرح الأمثلة في أبسط صورة لها. لذلك من الأفضل دائمًا أن تتأكد من فهمك لهذه المفاهيم وللأمثلة البسيطة وأن تُدرّب يدك على استخدامها وعلى تجربة أمثلة أكثر عمقًا. فكلما أتقنت لغة البرمجة جافا كلما ازدادت خبرتك في الأندرويد
    1 نقطة
  10. شرح وافي و رائع شكرا لك كانت مراجعه رائعه . ولكن هل هكذا انتهت الجافا ويمكنني الانتقال الي اندرويد استوديو ام انه ينقصني شئ ما
    1 نقطة
×
×
  • أضف...