Meningkatkan Aplikasi PHP Lama



Baru-baru ini saya memiliki kesempatan sesekali untuk bekerja dengan beberapa aplikasi PHP lama. Saya memperhatikan beberapa anti-pola umum yang harus diperbaiki. Artikel ini bukan tentang cara menulis ulang aplikasi PHP lama untuk <masukkan nama kerangka kerja yang indah di sini>, tetapi cara membuatnya lebih mudah untuk dipelihara dan tidak merepotkan untuk dikerjakan.



Antipattern # 1: kredensial dalam kode



Ini adalah pola terburuk yang pernah saya temui. Dalam banyak proyek, kode berversi di-hardcode dengan informasi penting, seperti nama dan kata sandi untuk mengakses database. Jelas, ini adalah praktik yang buruk, karena tidak memungkinkan pembuatan lingkungan lokal, karena kode tersebut terikat ke lingkungan tertentu. Selain itu, siapa pun yang memiliki akses ke kode dapat melihat kredensial yang biasanya sesuai untuk lingkungan produksi.



Untuk memperbaikinya, saya lebih suka metode yang berfungsi untuk aplikasi apa pun: instal paket phpdotenv , yang memungkinkan Anda membuat file lingkungan dan mengakses variabel menggunakan supervariabel lingkungan.



Mari buat dua file: .env.examplesatu yang akan diversi dan berfungsi sebagai template untuk file tersebut.env, yang akan berisi kredensial. File tersebut .envtidak berversi, jadi tambahkan ke .gitignore. Ini dijelaskan dengan baik dalam dokumentasi resmi .



File Anda .env.exampleakan mencantumkan kredensial:



DB_HOST=
DB_DATABASE=
DB_USERNAME=
DB_PASSWORD=


Dan datanya sendiri akan ada di file .env:



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


Dalam file biasa, muat .env:



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


Kemudian dapat diterapkan ke data akuntansi menggunakan, katakanlah $_ENV['DB_HOST'].



Tidak disarankan untuk menggunakan paket dalam operasi "sebagaimana adanya", untuk ini lebih baik:



  • Masukkan variabel lingkungan ke dalam runtime penampung Anda jika Anda memiliki penerapan berbasis Docker, atau ke dalam konfigurasi HTTP sisi server jika memungkinkan.
  • Cache variabel lingkungan untuk menghindari overhead pembacaan .env pada setiap permintaan. Beginilah cara Laravel melakukannya .


File kredensial dapat dihapus dari riwayat Git .



Antipattern # 2: jangan gunakan Composer



Dulu sangat populer memiliki folder lib dengan perpustakaan besar seperti PHPMailer. Ini harus dihindari dengan segala cara yang mungkin terkait pembuatan versi, jadi dependensi ini harus dikelola dengan Composer . Maka akan sangat mudah bagi Anda untuk melihat versi paket mana yang sedang digunakan dan memperbarui jika perlu.



Jadi instal Komposer dan gunakan untuk mengelola.



Antipattern # 3: tidak ada lingkungan lokal



Sebagian besar aplikasi yang saya gunakan hanya memiliki satu lingkungan: produksi.





Tetapi dengan menghilangkan anti-pola # 1, Anda dapat dengan mudah menyesuaikan lingkungan lokal Anda. Anda mungkin memiliki beberapa konfigurasi Anda yang di-hardcode, seperti jalur boot, tetapi sekarang Anda dapat memindahkannya ke .env.



Saya menggunakan Docker untuk membuat lingkungan lokal. Ini bekerja sangat baik untuk proyek lama karena mereka sering menggunakan versi PHP yang lebih lama yang tidak Anda inginkan atau tidak dapat Anda instal.



Anda dapat menggunakan layanan seperti PHPDocker , atau menggunakan file kecil docker-compose.yml.



Antipattern # 4: jangan gunakan folder Publik



Ternyata sebagian besar proyek lama ini dapat diakses dari folder root mereka. Artinya, file apa pun di root akan tersedia untuk dibaca publik. Ini sangat buruk ketika penyerang (seperti skrip kiddie) mencoba mengakses file yang disertakan secara langsung, karena Anda mungkin tidak dapat menentukan output jika skrip mengakses semua file yang disertakan secara langsung.



Jelas, situasi ini tidak sesuai dengan penggunaan .envatau Komposer, karena membuka folder vendor adalah ide yang buruk . Ya, ada beberapa trik untuk melakukan ini; tetapi jika memungkinkan, pindahkan semua file PHP yang terbuka untuk klien ke dalam folder Publicdan ubah konfigurasi server sehingga folder ini menjadi folder root untuk aplikasi Anda.



Saya biasanya melakukan ini:



  • Buat folder dockeruntuk file yang terkait dengan Docker (konfigurasi Nginx, PHP Dockerfile, dll.).
  • Saya membuat folder apptempat saya menyimpan logika bisnis (layanan, kelas, dll.).
  • Saya membuat folder publictempat saya menyimpan skrip dan sumber daya PHP (JS / CSS) terbuka untuk klien. Ini adalah folder root aplikasi dari sudut pandang klien.
  • Saya membuat file .envdan .env.example.


Antipattern # 5: Masalah keamanan yang parah



Aplikasi PHP, terutama yang lebih tua yang tidak menggunakan kerangka kerja, sering mengalami masalah keamanan yang parah:



  • Karena kurangnya pelolosan parameter dalam kueri, ada bahaya injeksi SQL. Untuk mencegahnya, gunakan PDO!
  • Ada bahaya injeksi XSS karena tampilan data pengguna yang tidak lolos. Gunakan htmlspecialchars untuk mencegahnya.
  • . , , , .
  • - CSRF-. Anti-CSRF, .
  • Enkripsi kata sandi yang buruk. Saya telah melihat banyak proyek masih menggunakan SHA-1 dan bahkan MD5 untuk hashing kata sandi. PHP 5.5 out of the box memiliki dukungan yang baik untuk BCrypt, sayang untuk tidak menggunakannya. Untuk mentransfer kata sandi dengan nyaman, saya lebih suka memperbarui hash di database saat pengguna masuk. Hal utama adalah memastikan bahwa kolom passwordtersebut cukup panjang untuk menampung kata sandi BCrypt, VARCHAR (255) baik-baik saja. Berikut adalah pseudocode untuk membuatnya lebih jelas:



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


Antipattern # 6: tidak ada tes



Ini sangat umum di aplikasi lama. Hampir tidak mungkin untuk mulai menulis pengujian unit untuk seluruh aplikasi, sehingga Anda dapat menulis pengujian fungsional.





Ini adalah pengujian tingkat tinggi untuk membantu Anda memastikan bahwa pemfaktoran ulang berikutnya dari aplikasi Anda tidak merusaknya. Tesnya bisa sederhana, misalnya, kita meluncurkan browser dan masuk ke aplikasi, lalu menunggu kode HTTP pada keberhasilan operasi dan / atau pesan yang sesuai di halaman akhir. Untuk pengujian, Anda dapat menggunakan PHPUnit atau Cypress atau codeception .



Antipattern # 7: Penanganan Kesalahan Buruk



Jika (atau kemungkinan besar) sesuatu rusak, Anda perlu mencari tahu dengan cepat. Tetapi banyak aplikasi lama tidak menangani kesalahan dengan baik, mengandalkan kelonggaran PHP.



Anda harus bisa menangkap dan mencatat kesalahan sebanyak mungkin untuk memperbaikinya. Ada artikel bagus tentang topik ini .



Selain itu, akan lebih mudah bagi Anda untuk menemukan tempat terjadinya kesalahan jika sistem memberikan pengecualian tertentu.



Antipattern # 8: variabel global



Saya pikir saya tidak akan pernah melihat mereka lagi sampai saya mulai mengerjakan proyek lama. Variabel global membuat pembacaan dan pemahaman tentang perilaku kode tidak dapat diprediksi. Singkatnya, itu jahat .



Lebih baik menggunakan injeksi ketergantungan sebagai gantinya , karena ini memungkinkan Anda untuk mengontrol instance mana yang digunakan dan di mana. Misalnya, paket Jerawat telah bekerja dengan baik .



Apa lagi yang perlu ditingkatkan?



Bergantung pada nasib aplikasi atau anggaran, ada beberapa langkah lagi yang dapat Anda lakukan untuk meningkatkan proyek Anda.



Pertama, jika aplikasi berjalan pada versi PHP yang lebih lama (di bawah 7), coba perbarui. Paling sering, ini tidak menyebabkan masalah besar, dan yang paling penting, akan memakan sebagian besar waktu untuk menyingkirkan panggilan mysql_ calls, jika ada. Untuk memperbaikinya dengan cepat, Anda dapat menggunakan pustaka serupa , tetapi lebih baik menulis ulang semua permintaan untuk PDO sehingga semua parameter di-escape pada saat yang sama.



Jika aplikasi tidak menggunakan pola MVC, yaitu logika bisnis dan templat dipisahkan, maka inilah saatnya untuk menambahkan pustaka templat (saya tahu bahwa PHP adalah bahasa templat, tetapi pustaka modern jauh lebih nyaman), misalnya, Smarty, Twig atau Blade.



Terakhir, dalam jangka panjang, yang terbaik adalah menulis ulang aplikasi Anda dalam kerangka kerja PHP modern seperti Laravel atau Symfony. Anda akan memiliki semua alat yang Anda butuhkan untuk pengembangan PHP yang aman dan cerdas. Jika aplikasinya besar, maka saya sarankan menggunakan pola pencekik untuk menghindari penulisan ulang big bang , yang mungkin (dan mungkin akan) berakhir buruk. Oleh karena itu, Anda dapat memigrasikan bagian-bagian kode yang sedang Anda kerjakan ke sistem baru, menjaga bagian kerja lama tetap utuh hingga muncul.



Ini adalah pendekatan efektif yang memungkinkan Anda membuat lingkungan PHP modern untuk pekerjaan Anda sehari-hari, tanpa membekukan fitur selama berminggu-minggu atau berbulan-bulan, tergantung pada proyeknya.



All Articles