PHP’yi tartışırken, odadaki filden kaçınmanın bir anlamı yok; PHP eskiden gerçekten vasat bir araçtı ve bu muhtemelen yetersiz bir ifadedir. Aslında, son zamanlarda insanların neden PHP’yi sevmediği konusunu ele alan bir makale gördüm. Ancak, kişisel deneyimime göre, geliştiriciler genellikle PHP’nin gerçekte ne olduğunu düşündüklerini karıştırırlar.
Gerçek şu ki, PHP itibarını bir yerden almıştır. Ancak PHP v4 ve öncesi eski, karanlık günler çok geride kaldı. Dehşet içinde çığlık atarak kaçmasaydınız, PHP’nin geliştiğini ve geliştiğini görürdünüz.
Bu makalede, hem dilin içinde hem de tamamlayıcı olarak bulunan araçları gözden geçirerek modern bir PHP geliştirme ortamının nasıl olduğunu ele alacağım. Günümüzde web geliştirmenin içerdiği karmaşıklıklar ile dili tek başına yargılayamazsınız. Yüksek kaliteli yazılımlar oluşturmanıza yardımcı olan tüm uydu teknolojilerinden haberdar olmanız gerekir.
Makalenin sonunda, PHP’nin ne kadar berbat olduğuna dair kesinliğiniz hakkında ikinci düşünceleriniz olacağını umarız. Ancak, eğer bir PHP hayranıysanız, seçiminizi savunmak için daha fazla nedeniniz olacak. Başlayalım!
Modern PHP nedir?
PHP’yi harika yapan şeyin ayrıntılarına atlamadan önce, modern PHP için bir tanım oluşturalım. Yazma sırasında, PHP v8.1.0 gün ışığına çıktı, PHP Vakfı gerçeğe dönüşmek üzere ve PHP v5.6 ömrünün sonuna yaklaşıyor. Bu nedenle, modern PHP’den bahsettiğimde, v7 ve sonraki sürümlerden bahsediyorum.
v5.0’da yeniden yazıldığından beri, dilin ve araçlarının gelişimi etkileyici olmuştur. PHP v5.0, PHP’nin tarihinde bir dönüm noktası oluşturarak onu gerçek nesne yönelimli diller alanına getirdi.
Bir başka farklı sıçrama, amatör ve profesyonel gelişim arasındaki çizgiyi kesinlikle çizen bir PHP bağımlılık yöneticisi olan Composer’ın piyasaya sürülmesiydi. Ancak, kendimi biraz ileri alıyorum, bunu daha sonra derinlemesine ele alacağız. Son birkaç sürümde PHP’de yapılan bazı önemli iyileştirmeleri gözden geçirelim.
v7.x’ten beri PHP dil geliştirmeleri
3 Aralık 2015’te piyasaya sürülen PHP v7.0’dan bu yana, tür bildirimleri, yerleşik şifreleme, karmaşık veri yapıları için destek, adlandırılmış bağımsız değişkenler ve nitelikler gibi birkaç heyecan verici yeni özellik tanıtıldı.
Sözdizimi ayrıca arrow işlevleri, spaceship operatörü ve boş birleştirme gibi bazı güçlü iyileştirmeler yaşadı. Her yeni sürüm, bir öncekine göre önemli performans iyileştirmeleri ile birlikte geldi.
Bu yeni özelliklerin her biri, PHP’yi üç veya dört sürüm önce bırakan biri için oldukça şok edici olabilir. Bu harika özelliklerden en iyi şekilde yararlanmak için muhtemelen yoğun bir PHP kullanıcısı olmanız gerekir, ancak PHP’yi daha rahat kullananlarımız için, PHP günlük kullanım durumlarına göre uyarlanmış ek yeni özellikler sunmuştur.
Artık en son PHP sürümlerinin sunduğu özellikleri kavradığımıza göre, araç kutumuzu oluşturalım. Aşağıdaki bölümlerde, PHP’de profesyonel yazılım geliştirme söz konusu olduğunda vazgeçilmez olduğunu düşündüğüm bazı araçları tartışacağım. Artımlı sırayla sunulurlar, yani bunun benimsemenin en kolay yolu olacağına inanıyorum.
Hata ayıklayıcılar
XDebug ve ZendDebugger gibi hata ayıklayıcıların kullanıma sunulmasından önce, geliştiriciler bir uygulamanın hatalı davranışının temel nedenini anlamak için aşırı zaman harcamak zorunda kaldılar.
Pratikte hata ayıklama, bir programın yürütülmesi sırasında değişkenlerin içeriğine bakmayı içerir.
Genel olarak PHP toplu modda kullanılır, yani çıktı yalnızca komut dosyası tamamlandıktan sonra görünür olur, bu da geliştiricilerin hata oluştuğunda bağlamın ne olduğunu tahmin etmelerini zorlaştırır.
Ek olarak, bu görev için mevcut olan var_dump, echo ve print_r gibi araçlar, geride iz bırakma, hassas bilgileri açığa çıkarma ve kötü niyetli saldırganlar için çıtayı düşürme konusunda yüksek risk taşır.
Hem XDebug hem de ZendDebugger, yukarıda bahsedilen sorunları çözmek için PhpStorm ve VS Code gibi modern IDE’lerle iyi çalışır. Doğrudan komut satırından geçmeyi tercih ederseniz, phpdbg v5.6’dan beri PHP ile birlikte gelir.
Bağımlılık yönetimi
Dış kitaplıkları bağımlılık olarak içe aktarmak, PHP’de gerçek bir acıydı. Ancak PHP’nin olgunluğundaki en belirgin değişikliklerden biri Composer’ın piyasaya sürülmesiyle geldi. Composer’dan önce PHP, aynı sorunu daha ilkel bir şekilde çözen PEAR’ı kullanıyordu.
Örneğin, PEAR kullanarak bireysel proje bağımlılıklarına sahip olmak karmaşıktır. PEAR ile bağımlılık yönetimi ya hep ya hiç durumudur, bu nedenle, özellikle her biri farklı veya birbiriyle çelişen bir dizi bağımlılığa bağlıysa, aynı sunucuda birkaç proje çalıştırmak zordur.
Öte yandan, Composer ile bağımlılık yönetimi çok daha basit. Her projenin kendi composer.json ve satıcı klasörleri vardır ve her şeyi kendi içinde tutar.
Composer’ın bir diğer büyük avantajı, bir bağımlılık ağacına en uygun olanı belirlemek için yerleşik zekaya sahip olan sürüm oluşturma sistemidir; kendi bağımlılıkları olan bağımlılıkları düşünün. PEAR ise bu alanda çok kötü bir iş çıkarıyor.
Günümüzde, PHP’nin en iyi uygulaması, Composer’a aşina olmayı gerektirir. Ele alacağımız araçların çoğu, çalışma ortamınızda kullanılabilirliğini gerektirir.
MVC çerçeveleri
Önemsiz olmayan bir uygulama oluşturuyorsanız, müşterinizin sorununu gerçekten çözebilmeniz için büyük olasılıkla çok sayıda ortak kod oluşturmanız gerekecek. Kimlik doğrulama, yönlendirme ve veritabanı yönetimi gibi sorunları düşünün.
PHP’nin eski günlerinde bunlar gerçek bir meydan okumaydı. Günümüzde, göreviniz için temel olarak kullanabileceğiniz Symfony ve Laravel başta olmak üzere birçok MVC çerçevesi mevcuttur. Symfony ve Laravel, geniş topluluk desteği ve yaygın kullanımla övünürler.
Otomatik test
Otomatik test araçları, yazılım geliştirme endüstrisinde bir standart haline geldi. Her dilin kendi araçları vardır ve PHP için en büyük oyuncu kesinlikle phpUnit‘tir.
phpUnit başlangıçta bir birim test çerçevesi olarak tasarlandı, ancak diğer araçlar, uçtan uca ve entegrasyon testi gibi diğer test türlerini sağlamak için onu genişletmeye yardımcı oldu.
phpUnit’i kullanmak oldukça basittir. Aşağıdaki gibi bir sınıfınız olduğunu söyleyin:
1 2 3 4 5 6 7 8 9 10 11 12 13 | <?php namespace TasarimKodlama; class HesapMakinesi { public function topla(int $a, int $b): int { return $a + $b; } } |
Kodu okurken, muhtemelen çalışacağını varsayıyorsunuz. Ancak phpUnit ile güven düzeyinizi oluşturmanıza ve doğrulamanıza yardımcı olacak bir dizi tekrarlanabilir test tanımlayabilirsiniz. Örneğin, bir test durumu aşağıdaki gibi görünecektir:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | <?php use PHPUnit\Framework\TestCase; use LeewayAcademy\HesapMakinesi; class HesapMakinesiTest extends TestCase { public function testTopla() { $sut = new HesapMakinesi(); $this->assertEquals(3, $sut->topla(1, 2)); $this->assertEquals(10, $sut->topla(5, 5)); $this->assertEquals(10, $sut->topla(0, $sut->topla(4, 6))); } } |
Yukarıdaki kod, farklı girdi kümeleriyle add yöntemini çalıştırır, ardından çıktının beklenenle eşleştiğini doğrular. Aşağıdaki komutu kullanarak testleri phpUnit ile çalıştırabilirsiniz:
1 2 3 | php vendor/phpunit/phpunit/phpunit --no-configuration --filter HesapMakinesiTest --test |
Yukarıdaki kod aşağıdaki gibi bir çıktı üretecektir:
1 2 3 4 5 6 | Testing started at 10:07 ... PHPUnit 9.5.11 by Sebastian Bergmann and contributors. Time: 00:00.006, Memory: 4.00 MB OK (1 test, 3 assertions) |
Bu tür bir testi istediğiniz kadar çalıştırabilirsiniz. Hepsi geçerse, uygulamanızın yapması gerekeni yaptığına dair gerçek bir kanıtınız olacaktır. Tabii ki, bu araçlar yalnızca yazdığınız testler kadar iyidir, ancak bu tamamen başka bir tartışma.
Bahsetmeye değer diğer araçlar arasında Codeception ve behat bulunur. Her ikisi de altında phpUnit kullanır, ancak test yazmak için farklı yaklaşımları vardır.
Statik analiz araçları
Statik analiz eksikliği, PHP ve diğer derlenmemiş diller için büyük bir dezavantajdı. Bazı hatalar, belirsiz yürütme yollarında o kadar iyi gizlenmişti ki, normal test durumlarında onları bulmak çok zordu. Şimdi sadece birkaçını saymak gerekirse phpstan, Psalm ve Exakat’ımız var. Örneğin, aşağıdaki hatayı göz önünde bulundurun:
1 2 3 4 5 6 7 8 9 10 11 12 | <?php function f(int $p): int { return $p * 2; } $a = 'M'; echo f($a); |
Statik analiz araçlarıyla, yukarıdaki gibi bir type uyuşmazlığı hatası, kodu çalıştırmadan aşağıdakine benzer bir komut vererek tespit edilebilir:
1 2 3 | vendor/bin/phpstan analyse test.php --level 5 |
Yukarıdaki kod aşağıdaki çıktıyı üretecektir:
1 2 3 4 5 6 7 8 9 10 | 1/1 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100% ------ ---------------------------------------------------------- Line test.php ------ ---------------------------------------------------------- 10 Parameter #1 $p of function f expects int, string given. ------ ---------------------------------------------------------- [ERROR] Found 1 error |
Artık, aksi halde gözden kaçabilecek hatalar hakkında çok kesin bilgilere sahipsiniz. Bu araçları sürekli bir entegrasyon hattına dahil ederek veya Git Hooks’un bir parçası olarak çalıştırarak kod tabanınızın kalitesini daha kolay iyileştirebilirsiniz.
Dağıtım araçları
Bir geliştiricinin işi, son kod satırını yazdıktan sonra bitmez. Bir hedef kitleye ulaşmak için uygulamanızın önce bir üretim sunucusuna ulaşması gerekir.
PHP’nin eski sürümlerinde, uygulamanızı dağıtmak için yeni dosyaları uzak bir konuma itmek gerekir. Ancak günümüzde durum biraz daha karmaşıktır. Her şeyi çalışır duruma getirmek için muhtemelen veritabanı güncellemelerini, dizin izinlerini ve çok sayıda başka küçük görevi yerine getirmeniz gerekecek. Çoğu zaman, bu eylemlerden birinin eksik olması veya farklı bir sırada çalıştırılması, tüm dağıtımın başarısız olmasına neden olur.
PHP ekosistemi, otomatikleştirilmiş test araçları gibi, uygulamanızı üretime almak ve gerektiğinde güncel tutmak için harika araçlar sağlayarak muazzam baş ağrılarını önler. Bunlardan bazıları Deployer, Rocketeer, Pomander ve easydeploy’dur. Örnek olarak, bir müşterinin projesi için kullandığım Dağıtıcı için bir yapılandırma:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | <?php namespace Deployer; require 'recipe/codeigniter.php'; // Project name set('application', 'APP'); // Project repository set('repository', 'git@bitbucket.org:maurochojrin/REPO.git'); set('branch', 'master'); set('default_stage', 'prod'); // [Optional] Allocate tty for git clone. Default value is false. set('git_tty', true); // Shared files/dirs between deploys add('shared_files', [ 'application/config/database.php', 'app_env.php', ]); add('shared_dirs', [ 'application/sessions', 'application/logs', 'assets/uploads/excel', 'logs', ]); // Writable dirs by web server add('writable_dirs', [ 'application/sessions', 'assets/uploads', 'application/logs', ]); // Hosts host('THE_HOST') ->stage('prod') ->identityFile('~/.ssh/MauroChojrin.pem') ->set('user', 'ubuntu') ->set('deploy_path', '~/{{application}}'); // Tasks task('build', function () { run('cd {{release_path}} && build'); }); task('pwd', function () { $result = run('pwd'); writeln("Current dir: $result"); }); // [Optional] if deploy fails automatically unlock. after('deploy:failed', 'deploy:unlock'); |
Bu yapılandırma yerindeyken, üretime yeni bir sürüm gönderdiğimde, aşağıdaki komutu çalıştırmam yeterli:
1 2 3 | dep deploy |
Komut dosyası, uygulamayı kullanıcılar için kullanılabilir hale getirmek için gereken her görevi uzaktan çalıştırır. Dosyaları hala FTP üzerinden gönderiyorsanız, muhtemelen bu araçları kontrol etmek istersiniz.
Asynchronous yürütme
PHP söz konusu olduğunda bir başka yaygın şikayet, eşzamansız yürütme desteğinin olmamasıdır. Swoole ve ReactPHP gibi bu yönde hedeflenen birkaç proje var. Örneklere Göre Swoole deposundan alınan aşağıdaki koda bir göz atın:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | #!/usr/bin/env php <?php declare(strict_types=1); /** * How to run this script: * docker exec -t $(docker ps -qf "name=client") bash -c "time ./io/blocking-io.php" * * This script takes about 3 seconds to finish, and prints out "12". * * Here the PHP function sleep() is used to simulate blocking I/O. The non-blocking version takes about 2 seconds to * finish, as you can see in script "non-blocking-io.php". */ (function () { sleep(2); echo '1'; })(); (function () { sleep(1); echo '2'; })(); |
Engellemeyen muadili ile karşılaştırın:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | #!/usr/bin/env php <?php declare(strict_types=1); /** * How to run this script: * docker exec -t $(docker ps -qf "name=client") bash -c "time ./io/non-blocking-io.php" * * This script takes about 2 seconds to finish, and prints out "21". * * Here the Swoole function co:sleep() is used to simulate non-blocking I/O. If we update the code to make it work in * blocking mode, it takes about 3 seconds to finish, as you can see in script "blocking-io.php". * * To see how the code is executed in order, please check script "non-blocking-io-debug.php". */ go(function () { co::sleep(2); echo '1'; }); go(function () { co::sleep(1); echo '2'; }); |
Sözdizimsel olarak oldukça benzer görünüyorlar, ancak ikinci sürüm, Swoole’un paralel işleme gücünden yararlanarak nihai sonuca ulaşmak için gereken süreyi azaltıyor.
PHP v8.1’de Fibers, kullanıma hazır bir özellik olarak tanıtıldı, bu nedenle hedefiniz zaman uyumsuzsa, PHP’den ayrılmadan bunu başarmanızı engelleyen hiçbir şey yoktur.
Sonuç
PHP uzun bir yol kat etti. Ne yazık ki, her PHP geliştiricisi bu en iyi uygulamaları takip etmedi, bu yüzden hala birçok spagetti kodu bulabilirsiniz. Ancak bu, bir aracın eksikliklerinden çok bireyin sorumluluğunu yansıtır.
İyi tarafı, isterseniz PHP ile seviye atlamak için birçok mükemmel kaynak var. Umarım bu makaleden hoşlanmışsınızdır. Henüz yapmadıysanız, umarım şimdi bir PHP hayranısınızdır veya en azından bir şans vermeye isteklisinizdir. PHP’nin itibarını tersine çevirelim.
Kaynak: https://blog.logrocket.com/











Yorum Yap