تحديث تطبيق PHP قديم



لقد أتيحت لي مؤخرًا فرصة عرضية للعمل مع العديد من تطبيقات PHP القديمة. لقد لاحظت بعض الأنماط المضادة الشائعة التي يجب إصلاحها. لا تتناول هذه المقالة كيفية إعادة كتابة تطبيق PHP قديم من أجل <أدخل اسم إطار العمل الرائع هنا> ، ولكن كيفية جعله أكثر قابلية للصيانة وأقل صعوبة في العمل به.



Antipattern # 1: بيانات الاعتماد في الكود



هذا هو الأكثر شيوعًا من أسوأ الأنماط التي صادفتها. في العديد من المشاريع ، يتم ترميز التعليمات البرمجية ذات الإصدار الثابت بمعلومات مهمة ، مثل الأسماء وكلمات المرور للوصول إلى قاعدة البيانات. من الواضح أن هذه ممارسة سيئة ، لأنها لا تسمح بإنشاء بيئات محلية ، لأن الكود مرتبط ببيئة معينة. بالإضافة إلى ذلك ، يمكن لأي شخص لديه حق الوصول إلى الكود رؤية بيانات الاعتماد المناسبة عادة لبيئة الإنتاج.



لإصلاح ذلك ، أفضل طريقة تعمل مع أي تطبيق: تثبيت حزمة phpdotenv ، والتي تتيح لك إنشاء ملف بيئة والوصول إلى المتغيرات باستخدام متغيرات البيئة.



لنقم بإنشاء ملفين: .env.exampleأحدهما سيتم إصداره ويعمل كقالب للملف.env، والتي سوف تحتوي على بيانات الاعتماد. الملف .envليس له إصدار ، لذا قم بإضافته إلى .gitignore. هذا موضح بشكل جيد في الوثائق الرسمية . سيقوم



ملفك .env.exampleبسرد بيانات الاعتماد:



DB_HOST=
DB_DATABASE=
DB_USERNAME=
DB_PASSWORD=


وستكون البيانات نفسها في الملف .env:



DB_HOST=localhost
DB_DATABASE=mydb
DB_USERNAME=root
DB_PASSWORD=root


في ملف عادي ، قم بتحميل .env:



$dotenv = Dotenv\Dotenv::createImmutable(__DIR__);
$dotenv->load();


ثم يمكن أن تنطبق على البيانات المحاسبية باستخدام ، على سبيل المثال $_ENV['DB_HOST'].



لا يوصى باستخدام الحزمة في العملية "كما هي" ، فمن الأفضل:



  • أدخل متغيرات البيئة في وقت تشغيل الحاوية الخاصة بك إذا كان لديك نشر مستند إلى Docker ، أو في تكوين HTTP من جانب الخادم إن أمكن.
  • متغيرات بيئة التخزين المؤقت لتجنب الحمل الزائد للقراءة .env عند كل طلب. هذه هي الطريقة التي يقوم بها Laravel .


يمكن إزالة ملفات الاعتماد من محفوظات Git .



Antipattern # 2: لا تستخدم الملحن



كان من الشائع جدًا أن يكون لديك مجلد lib به مكتبات كبيرة مثل PHPMailer. يجب تجنب هذا بكل طريقة ممكنة عندما يتعلق الأمر بالإصدار ، لذلك يجب إدارة هذه التبعيات باستخدام Composer . بعد ذلك سيكون من السهل جدًا عليك معرفة أي إصدار من الحزمة قيد الاستخدام وتحديثه إذا لزم الأمر.



لذا قم بتثبيت Composer واستخدامه في الإدارة.



Antipattern # 3: لا توجد بيئة محلية



معظم التطبيقات التي عملت معها كان لها بيئة واحدة فقط: الإنتاج.





ولكن من خلال التخلص من النمط المضاد رقم 1 ، يمكنك بسهولة تخصيص بيئتك المحلية. قد يكون لديك بعض من التكوين الخاص بك مشفرًا بشكل ثابت ، مثل مسارات التمهيد ، ولكن يمكنك الآن نقل ذلك إلى .env.



أستخدم Docker لإنشاء بيئات محلية. إنه يعمل جيدًا بشكل خاص للمشاريع القديمة لأنها غالبًا ما تستخدم إصدارات أقدم من PHP لا تريدها أو لا يمكنك تثبيتها.



يمكنك استخدام خدمة مثل PHPDocker ، أو استخدام ملف صغير docker-compose.yml.



Antipattern # 4: لا تستخدم المجلد العام



اتضح أن معظم هذه المشاريع القديمة يمكن الوصول إليها من مجلدات الجذر الخاصة بها. أي أن أي ملف في الجذر سيكون متاحًا للقراءة العامة. يعد هذا أمرًا سيئًا بشكل خاص عندما يحاول المهاجمون (مثل برنامج kiddie النصي) الوصول إلى الملفات المضمنة مباشرةً ، لأنك قد لا تتمكن من تحديد الإخراج إذا كان البرنامج النصي يصل إلى جميع الملفات المضمنة مباشرةً.



من الواضح أن هذا الموقف لا يتوافق مع استخدام .envأو Composer ، لأن فتح مجلد البائع فكرة سيئة . نعم ، هناك بعض الحيل للقيام بذلك ؛ ولكن إن أمكن ، انقل جميع ملفات PHP المفتوحة للعملاء إلى مجلد Publicوقم بتغيير تكوين الخادم بحيث يصبح هذا المجلد هو المجلد الجذر لتطبيقك.



عادة ما أفعل هذا:



  • قم بإنشاء مجلد dockerللملفات المتعلقة بـ Docker (تكوين Nginx ، PHP Dockerfile ، إلخ).
  • أقوم بإنشاء مجلد appأخزن فيه منطق الأعمال (خدمات ، فئات ، إلخ).
  • أقوم بإنشاء مجلد publicأخزن فيه نصوص PHP ومواردها (JS / CSS) مفتوحة للعملاء. هذا هو المجلد الجذر للتطبيق من وجهة نظر العملاء.
  • أقوم بإنشاء ملفات .envو .env.example.


Antipattern # 5: مشاكل أمنية فظيعة



غالبًا ما تعاني تطبيقات PHP ، خاصة التطبيقات القديمة التي لا تستخدم أطر عمل ، من مشكلات أمنية فادحة:



  • نظرًا لعدم وجود هروب من المعلمات في الاستعلام ، هناك خطر من حقن SQL. لمنعها ، استخدم PDO!
  • هناك خطر من حقن XSS بسبب عرض بيانات المستخدم التي لم يتم تسريبها. استخدم htmlspecialchars لمنعها.
  • . , , , .
  • - CSRF-. Anti-CSRF, .
  • تشفير كلمات المرور ضعيف. لقد رأيت العديد من المشاريع لا تزال تستخدم SHA-1 وحتى MD5 لتجزئة كلمة المرور. PHP 5.5 من خارج منطقة الجزاء به دعم جيد لـ BCrypt ، ومن العار عدم استخدامه. لنقل كلمات المرور بشكل مريح ، أفضل تحديث التجزئة في قاعدة البيانات أثناء تسجيل دخول المستخدمين. الشيء الرئيسي هو التأكد من أن العمود passwordطويل بما يكفي لاحتواء كلمات مرور BCrypt ، VARCHAR (255) جيد. إليك الشفرة الكاذبة لتوضيحها:



    <?php
    //    :    $
    //  :     
    if (strpos($oldPasswordHash, '$') !== 0 &&
        hash_equals($oldPasswordHash, sha1($clearPasswordInput))) {
        $newPasswordHash = password_hash($clearPasswordInput, PASSWORD_DEFAULT);
    
        //   password
    
        //  :    
    }
    
    //   
    if (password_verify($clearPasswordInput, $currentPasswordHash)) {
        //  :    
    }
    
    //   :    
    


Antipattern # 6: لا توجد اختبارات



هذا شائع جدًا في التطبيقات القديمة. من الصعب بدء كتابة اختبارات الوحدة للتطبيق بأكمله ، لذا يمكنك كتابة اختبارات وظيفية.





هذه اختبارات عالية المستوى لمساعدتك على التأكد من أن إعادة البناء اللاحق لتطبيقك لا يكسرها. يمكن أن تكون الاختبارات بسيطة ، على سبيل المثال ، نقوم بتشغيل المتصفح وإدخال التطبيق ، ثم ننتظر رمز HTTP عند نجاح العملية و / أو الرسالة المقابلة في الصفحة الأخيرة. للاختبارات ، يمكنك استخدام PHPUnit أو Cypress أو codeception .



Antipattern # 7: سوء معالجة الخطأ



إذا حدث (أو على الأرجح عند) شيء ما ، فأنت بحاجة إلى معرفة ذلك بسرعة. لكن العديد من التطبيقات القديمة لا تتعامل مع الأخطاء بشكل جيد ، حيث تعتمد على تساهل PHP.



يجب أن تكون قادرًا على اكتشاف وتسجيل أكبر عدد ممكن من الأخطاء لإصلاحها. هناك مقالات جيدة حول هذا الموضوع .



أيضًا ، سيكون من الأسهل عليك العثور على الأماكن التي تحدث فيها الأخطاء إذا ألقى النظام استثناءات محددة.



Antipattern # 8: المتغيرات العالمية



اعتقدت أنني لن أراهم مرة أخرى حتى بدأت العمل في المشاريع القديمة. المتغيرات العالمية تجعل قراءة وفهم سلوك الكود أمرًا لا يمكن التنبؤ به. باختصار ، إنه شر .



من الأفضل استخدام حقن التبعية بدلاً من ذلك ، لأنه يسمح لك بالتحكم في الحالات التي يتم استخدامها ومكانها. على سبيل المثال ، كان أداء حزمة Pimple جيدًا .



ما الذي يجب تحسينه أيضًا؟



اعتمادًا على مصير التطبيق أو الميزانية ، هناك عدة خطوات أخرى يمكنك اتخاذها لتحسين مشروعك.



أولاً ، إذا كان التطبيق يعمل على إصدار أقدم من PHP (أقل من 7) ، فحاول تحديثه. في أغلب الأحيان ، لا يسبب هذا مشاكل كبيرة ، والأهم من ذلك كله سيستغرق التخلص من المكالمات mysql_ calls، إن وجدت ، معظم الوقت . لإصلاح ذلك بسرعة ، يمكنك استخدام مكتبة مماثلة ، ولكن من الأفضل إعادة كتابة جميع طلبات PDO بحيث يتم تخطي جميع المعلمات في نفس الوقت.



إذا كان التطبيق لا يستخدم نموذج MVC ، أي منطق الأعمال والقوالب منفصلة ، فقد حان الوقت لإضافة مكتبة قوالب (أعرف أن PHP هي لغة قوالب ، لكن المكتبات الحديثة أكثر ملاءمة) ، على سبيل المثال ، Smarty أو Twig أو Blade.



أخيرًا ، على المدى الطويل ، من الأفضل إعادة كتابة تطبيقك في إطار عمل PHP حديث مثل Laravel أو Symfony. سيكون لديك جميع الأدوات التي تحتاجها لتطوير PHP آمن وذكي. إذا كان التطبيق كبيرًا ، فأنا أوصي باستخدام نمط strangler لتجنب إعادة كتابة الضجة الكبيرة ، والتي قد (وربما ستنتهي) بشكل سيء. لذلك ، يمكنك ترحيل تلك الأجزاء من الكود التي تعمل عليها حاليًا إلى النظام الجديد ، مع الحفاظ على أجزاء العمل القديمة سليمة حتى تصل إليها.



هذا نهج فعال يسمح لك بإنشاء بيئة PHP حديثة لعملك اليومي ، دون تجميد الميزات لأسابيع أو شهور ، حسب المشروع.



All Articles