Avatar
Ben Süleyman ERGEN. Siber güvenlik benim alanımdır. Bol bol ctf çözer ve write-up yazarım. Burada ise edindiğim tecrübeleri ve bilgileri paylaşıyorum.

CODEIGNITER 4 YAYINLANDI

CODEIGNITER 4 YAYINLANDI

ci4

Uzun bir zamandır Codeigniter 4 geliştirilme aşamasındaydı. Stabil sürümüne 24 şubat 2020 tarihinde yayınlandı. Şu an itibariyle 4.0.2 sürümüne ulaştı.

Fakat Codeigniter 4 ile neler değişti. Bu sürüm bize neler sunuyor. Yenilikler neler. Tüm bunları bu yazımda elimden geldiğince cevaplamaya çalışacağım.

Ben ve Codeigniter 4 ???

Geçen yıl kafamda bir ctf platformu projesi vardı. Bu projeyi php ile yapacaktım. Aynı zamanda laravel ve codeigniter 3 ile daha önceden tecrübem olmuştu. Projemi laravel gibi büyük bir framework ile yapmak istemiyordum. Çünkü framework çok büyük ve kurulumla gelen özelliklerinin yarısından fazlasını muhtemelen kullanmayacaktım. Codeigniter 3'e baktığımda ise güncel php özelliklerini taşımadığını biliyordum. Namespace, psr standartları vs..

O sıralar Codeignter 4'ün geliştirilme aşamasnda olduğunu öğrenmiştim. Beta sürümü yeni çıkmıştı. Bende hemen denedim. Resmi dökümantasyonunun üzerinden bir defa geçtikten sonra bilgisayarıma kurup denemeler yapmaya başladım. İlk izlenimlerim oldukça hoşuma gitmişti. Hala codeigniter 3 gibi basit ve sade. Aynı zamanda oldukça küçük bir boyutla geliyordu. Yaklaşık 3 MB.

Ardından Codeigniter 4 ile ctf platformuna başladım. 6 aydan uzun süredir Codeigniter 4 ile geliştiriyorum ve oldukça memnunum.

Projemin gitlab adresini şu şekilde bırakayım.

NELER DEĞİŞTİ

ci4-giris

Aslını söylemek gerekirse her şey tamamen değişti. Tüm framework sıfırdan yeniden yazıldı. Peki buna gerek var mıydı?

Codeigniter ilk sürümünden itibaren çok değişikliğe uğramadan geliştirilmişti. 1. 2. ve 3. sürümlerini kastediyorum. Fakat 4. sürüme geldiğinde frameworkte ciddi bir değişikliğe ihtiyaç olduğu biliniyordu. Bu yüzden Codeigniter topluluğu var olan kodu refactor etmek yerine, herşeyi silip yeniden yazmayı seçtiler. İlk commit 26 ağustos 2015 te atıldı. Ve yaklaşık olarak 5 yıl geliştirme süreci devam etti. Bu süre zarfında framework sıfırdan yazıldı.

Şimdik 4. sürümle beraber gelen değişikliklere bakalım.

DİZİN YAPISI

Codeigniter 4. sürümüyle standart haline gelen, Codeigntier 3 ten aşina olduğumuz dizin yapısını hala koruyor. Bu dizinleri şu şekilde özetleyebiliriz.

.
├── app/
├── public/
├── system/
├── tests/
├── writable/
├── env
└── spark
  • app dizini Codeignter 3 teki application dizinine karşılık geliyor. İsmi kısaltılmış. Arada başka bir fark yok.
  • public dizini projenin document root dizinidir. Kullandığınız server bu dizini işaret eder.
  • system frameworkün kendi dosya ve kodlarının bulunduğu dizindir.
  • tests dizini projenin unit testlerinin bulunduğu dizindir.
  • writable dizini logların, cache dosyaların, session dosyalarının ve buna benzeyen devamlı olarak değişen dosyaların bulunduğu dizindir.
  • env dosyası projeye ait ortam değişkenlerinin bulunduğu bir dosyadır.
  • spark Codeigniter 4 ile beraber gelen komut satırı işlemcisidir.

Bu noktada çok özet geçtiğimin farkındayım. Hadi bunları biraz daha detaylandıralım.

app Dizini

Bu dizin bizim asıl kodlarımızı yazacağımız dizindir. Bizi en çok ilgilendiren dizin de burasıdır. Codeigniter 3 ten aşina olduğumuz yapısını yine koruyor.

.
├── Config
├── Controllers
├── Database
├── Filters
├── Helpers
├── Language
├── Libraries
├── Models
├── ThirdParty
├── Views
├── Common.php
└── index.html

public Dizini

En önemli değişikliklerden birisi de burası. Projenin document root dizini public dizini olarak değişti. Peki bu ne demek. Bu sürümden itibaren kullandığımız server (apache, nginx, …) public dizinini document root olarak alacak.

Ayrıca projemizde bulunan javascript, css, resim gibi statik dosyalar da bu dizinde bulunacak. Yani bu dizinin amacı php gibi çalıştırılabilir bir dosya bulundurmamak. Bu dizinde bulunan tek php dosyası index.php dosyasıdır. Bu dosyada Codeigniter 4 için front controller olarak olarak adlandırılır. Bu dosya haricinde bu dizinde php dosyası bulunmamalıdır.

system Dizini

Codeigniter 3 ten aşina olduğumuz Codeigniter 4 frameworkünün kodlarının bulunduğu dizin. Bildiğiniz üzere bu dizine hiç bir surette dokunmuyoruz. Çünkü bu dizindeki dosyalarda yapacağımız bir değişiklik sürüm güncellemesi ile kaybolacaktır. Bunun yerine resmi codeigniter dökümantasyonundan Extending CodeIgniter bölümünü okuyarak Codeigniter'i nasıl extend edilir öğrenebilirsiniz.

tests Dizini

Codeigniter 4 ile gelen bir dizin. Bu dizin unit testlerimizi barındıracak.

writable Dizini

Codeigniter 4 ile gelen yeni bir dizin. Adından da anlaşılacağı üzere yazılabilir olarak işaretlenmesi gereken bir dizin. Linux sistemlerde chmod +w writable/ komutuyla veya windows sistemlerde windows explorerdan yazılabilir olarak işaretleyebiliriz.

Peki bu dizinde neler bulunuyor. Temel olarak ara bellek dosyaları, log dosyaları, session dosyaları gibi devamlı olarak değişen dosyalar bu dizinde bulunuyor. Zaten yazılabilir olarak işaretlenmesinin sebebi de bu.

env Dosyası

env dosyası projenin environment veriables dediğimiz ortam değişkenleri nin bulunduğu dosyadır. Bu dosya veritabanı kullanıcı bilgileri, projenin ana urli, cookie gibi birçok ayarının bulunduğu dosyadır.

Codeigniter ile gelen env dosyası sadece bir taslak dosyadır. Bizim bu dosyayı kullanmadan önce ismini .env olarak değiştirip kullanmamız gerekiyor. Aksi takdirde çalışmayacaktır.

spark Dosyası

Codeignter 4 ile gelen en önemli yeniliklerden biriside bu. spark Codeigniter 4 ile gelen komut satırı istemcisidir. Proje ile ilgili bir çok işlemi kolay bir şekilde yapmanıza olanak sağlıyor.

Hadi bu istemci ile neler yapabileceğimize bakalım. Dosyayı php ile çalıştırıyorum.

$ php spark 

CodeIgniter CLI Tool - Version 4.0.2 - Server-Time: 2020-01-19 14:10:36pm


CodeIgniter
  help               Displays basic usage information.
  list               Lists the available commands.
  namespaces         Verifies your namespaces are setup correctly.
  routes             Displays all of user-defined routes. Does NOT display auto-detected routes.
  serve              Launches the CodeIgniter PHP-Development Server.
  session:migration  Generates the migration file for database sessions.

Database
  db:seed            Runs the specified seeder to populate known data into the database.
  migrate            Locates and runs all new migrations against the database.
  migrate:create     Creates a new migration file.
  migrate:refresh    Does a rollback followed by a latest to refresh the current state of the database.
  migrate:rollback   Runs the "down" method for all migrations in the last batch.
  migrate:status     Displays a list of all migrations and whether they've been run or not.

php spark help ile yardım sayfasına bakabiliriz. Bir örnek yapalım.

$ php spark help

CodeIgniter CLI Tool - Version 4.0.2 - Server-Time: 2020-01-19 14:15:45pm

Description:
   Displays basic usage information.

Usage:
   help command_name

Arguments:
   command_name      The command name [default: "help"]

Böylelikle komutun ne yaptığını, aldığı parametreleri ve açıklamalarını, nasıl kullanıldığını öğrenebiliyoruz.

php spark namespaces

Bu komut ile projemizde tanımlı olan namespace leri görebiliyoruz.

php spark routes

Bize projemizde tanımladığımız routeleri yani urlleri görebiliyoruz. Örnek bir kullanım şu şekilde.

$ php spark routes

CodeIgniter CLI Tool - Version 4.0.2 - Server-Time: 2020-01-19 14:21:22pm

+----------------------------+--------+------------------------------------------------+
| Route                      | Method | Command                                        |
+----------------------------+--------+------------------------------------------------+
| /                          | get    | \App\Controllers\Home::index                   |
| migrations/([^/]+)/([^/]+) | cli    | \CodeIgniter\Commands\MigrationsCommand::$1/$2 |
| migrations/([^/]+)         | cli    | \CodeIgniter\Commands\MigrationsCommand::$1    |
| migrations                 | cli    | \CodeIgniter\Commands\MigrationsCommand::index |
| ci(.*)                     | cli    | \CodeIgniter\CLI\CommandRunner::index/$1       |
+----------------------------+--------+------------------------------------------------+

Yukarıda tanımlı routelar projenin ilk kurulum ile beraber gelen routelardır. Siz ekledikçe burada belirecektir.

php spark serve

Bu komutla php default serveri başlatabilirsiniz. Geliştirme sırasında kullanabileceğiniz güzel bir özelliktir.

$ php spark serve

CodeIgniter CLI Tool - Version 4.0.2 - Server-Time: 2020-01-19 14:30:33pm

CodeIgniter development server started on http://localhost:8080
Press Control-C to stop.

Komutu yukarıdaki şekilde çalıştırdığımızda default development serveri çalıştıracaktır. http://localhost:8080 adresine giderek web sayfasını görebilirsiniz.

spark Veritabanı Komutları

Önce veritabanı komutlarını listeleyelim ve ardından açıklayalım.

Database
  db:seed            Runs the specified seeder to populate known data into the database.
  migrate            Locates and runs all new migrations against the database.
  migrate:create     Creates a new migration file.
  migrate:refresh    Does a rollback followed by a latest to refresh the current state of the database.
  migrate:rollback   Runs the "down" method for all migrations in the last batch.
  migrate:status     Displays a list of all migrations and whether they've been run or not.

php spark db:seed ile tanımladığınız seederları çalıştırabilirsiniz. Bilmeyenler için seeder veritabanına eklemek istediğiniz default değerlerdir. Bu komut seed dosyalarını app/Database/Seeds dizininde arar.

php spark migrate yeni migrations dosyalarını çalıştırır.

php spark migrate:rollback Veritabanının bir önceki sürümüne dönmeyi sağlar.

php spark migrate:status mevcut migration sürümü ile ilgili bilgi verir.


Genel olarak dizin ve dosya yapısındaki değişiklikler bu şekilde. Daha detaylı bilgi için şuraya gidebilirsiniz: Application Structure

Controller

Şimdi gelelim Controller'lara.

Aslında CI4 ile gelen controller CI3'teki sadeliğini ve temel yapısını koruyor. Fakat yapması gereken işlemleri daha modern yöntemlerle yapıyor.

Controller bildiğimiz gibi gelen HTTP isteğinin nasıl işleneceğini/cevaplanacağını belirler. Codeigniter 4 ile gelen basit bir controller şu şekildedir.

<?php namespace App\Controllers;
use CodeIgniter\Controller;

class Home extends Controller
{
	public function index()
	{
		return view('welcome_message');
	}
}

CI4'te bütün controllerlar App\Controllers namespace'ine sahip olmalıdırlar. Bu isim alanı psr-4 standardına uygun olarak tanımlanmıştır. Bu CI4 ile gelen yeni bir özellik.

Şimdi gelelim değişikliklere.

initController

Normalde php de __contructor özel metodu ile (yani sınıf yapıcı fonksiyonu ile) sınıflarımızdan ilk nesne üretildiğinde yapmak istediğimiz işlemlerimizi yapıyorduk. Fakat CI4'te bu şekilde yapmak bazı noktalarda sizi zor durumda bırakabilir. Bunun için başka bir metodumuz var. initController metodu.

public function initController(RequestInterface $request, ResponseInterface $response, LoggerInterface $logger)
{
   parent::initController($request, $response, $logger);
}

Bu metod tıpkı bir yapıcı fonksiyon gibi çalışıyor. Artısı ise CI4 çalışma zamanına/sıralamasına daha iyi müdahale etmemizi sağlıyor.

Mesela siz controller çalışmadan yada controllerdan nesne üretilip hemen ardından çalışan bir hook tanımlamak istiyorsunuz. Bu işlemi normal yapıcı metodlar kullanarak yapamazdık. Çünkü yapıcı metod nesne üretildikten hemen sonra çalıştırılır ve bize bu arada bir işlem yapmamıza imkan vermez. Bu yüzden CI4 böyle bir metoda sahip.

Ayrıca HTTP ile gelen isteğin işlenmesi için gerekli olan sınıf değişkenlerine bu metod içerisinde ilk değerleri atanır. Bu sınıf değişkenleri şu şekildedir.

  • request Gelen request ile ilgili bilgiler bulunur.
  • response Gelen isteğe nasıl cevap verileceğini belirleyen sınıfın tutulduğu değişken
  • logger Loglama işlemleri için kullanılacak sınıf örneğinin tutulduğu değişken.

Başka bir güzel özellik ise kullanmak istediğimiz helper fonksiyonlarını otomatik olarak yüklemek için helpers isminde array tipinde bir değişkene sahip. Bu değişkene yüklemek istediğiniz helperları yazarak otomatik yüklenmesini sağlayabilirsiniz.

Validation

Codeigniter 4 te controller içinde validation işlemlerinizi kolay bir şekilde yapabilmeniz için bir kolaylıkla geliyor. Kurallarınızı tanımladıktan sonra $this->validate() fonksiyonu ile kontrol işleminizi yapabiliyorsunuz. Eğer validation başarılı olursa true aksi halde false dönüyor. Örnek aşağıda:

$rules = [
	'name' => 'required'
];

if (! $this->validate($rules))
{
	return redirect()->back()->with('errors', $this->validator->getErrors());
}

Validation işlemi başarısız olursa hataları almak için $this->validator->getErrors() fonksiyonunu kullanabilirsiniz. Bu size hataları dizi olarak verecektir.

Controller ile ilgili daha detaylı bilgiye şuradan ulaşabilirsiniz: CI4 Controllers

Model

Sıra geldi codeigniter 4 modeline. Model tam anlamıyla yenilenmiş ve geliştirilmiş. Yeni gelen özelliklere bakalım.

Önce basit bir model tanımlamasına bakalım.

<?php namespace App\Models;

use CodeIgniter\Model;

class UserModel extends Model
{
	protected $table      = 'users';
	protected $primaryKey = 'id';
	protected $returnType = User::class;

	protected $allowedFields = [
		'username', 'email', 'name'
	];

	protected $validationRules = [
		'username'      => 'required|min_length[3]|max_length[30]|alpha_numeric|is_unique[users.username,username,{username}]',
		'email'         => 'required|max_length[255]|valid_email|is_unique[users.email,email,{email}]',
		'name'          => 'required|min_length[3]|max_length[100]|string',
	];

	protected $useTimestamps = true;
	protected $useSoftDeletes = true;
}

Model tanımlamamızı Model sınıfından extend ederek tanımlıyoruz. Ardından $table değişkeni ile tablo ismini ve $primaryKey değişkeni ile tablo için tanımladığımız ana anahtarımızı belirliyoruz.

Veri dönüş değerinizi belirlemeniz de artık mümkün. Tablodan bir kayıt getirdiğinizde bu kaydı bir nesne, array ve entity olarak getirmeniz mümkün. Entity codeigniter'in sağladığı veritabanından gelen her bir kaydı özel bir nesne olarak ifade etmek için kullanabileceğiniz bir sınıf. Detaylarını sonraki yazılarımda paylaşacağım.

protected $returnType = 'object';

Başka bir güzel şey ise codeigniter'in tablosa sadece belli kolonları değiştirmesine izin vermemizi sağlayan özelliği. $allowedFields değişkeni ile hangi kolonların değiştirilebilir olduğunu belirleyebiliyorsunuz. Diğer hiç bir kolon değiştirilmeyecektir.

protected $allowedFields = [
	'username', 'email', 'name'
];

Yukarıdaki örnekte sadece username email ve name alanları değiştirilebilecek.

Sıra geldi benim yeni modelin en sevdiğim özelliğine. Form validation işlemlerini oldukça kolaylaştıran bir özellik. $validationRules alanına istediğiniz doğrulama kurallarını yazarak modelin bu kuralları her ekleme, güncelleme işleminde kontrol etmesini sağlayabiliyoruz.

Bu özellik sayesinde veritabanına her eklenecek ve değiştirelecek her bir kayıt otomatik olarak bu doğrulamadan geçecek. Eğer vu doğrulama başarısız olursa veribabanı işlemi gerçekleştirilmeyecek.

Bir örnekle üzerinde biraz inceleyelim ve her bir kuralı tek tek açıklayalım:

protected $validationRules = [
	'username'      => 'required|min_length[3]|max_length[30]|alpha_numeric|is_unique[users.username,username,{username}]',
	'email'         => 'required|max_length[255]|valid_email|is_unique[users.email,email,{email}]',
	'name'          => 'required|min_length[3]|max_length[100]|alpha_numeric_space',
];
  • username alanı 3 ile 30 karakter arasında olacak. Yalnızca alfanümerik karakterlerden olaşacak ve users tablosunda uniq yani eşsiz olacak.
  • email max 255 karakter ve geçerli bir email olarak. users tablosunda sadece bir defa bulunacak.
  • name alanı 3 ile 100 karakter arasında sadece alfanümerik ve boşluk karakterlerinden oluşacak.

Eğer veritabanı işlemlerinizde kayıtlarla ilgili oluşturulma, güncellenme zamanlarınıda tutmak istiyorusanız $useTimestamps değerini true olarak işaretlemeniz yeterli. Codeigniter 4 gerikalan işlemleri sizin yerinize yapacaktır.

Bu alan veritabanında created_at ve updated_at kolonlarına ihtiyaz duyar. Veritabanında bu kolonların olduğundan emin olun.

Eğer sildiğiniz verilerin gerçekten silinmesini istemiyorsanız $useSoftDeletes değerini true olarak belirleyin. Bunu yaptığınız zaman bir kaydı silmek istediğinizde Codeigniter deleted_at kolonuna silinme zamanını girecektir. Siz özellikle belirtmedikçe veritabanı sonuçlarında silinen (sözde) kayıtları göstermeyecektir.

Model ile ilgili daha detaylı bilgiye şuradan ulaşabilirsiniz: CI4 Using CodeIgniter’s Model

Debugbar

Codeigniter 4 ile gelen en önemli özelliklerden bir taneside bu. Debugbar. Gerçekten çok kullanışlı ve geliştirme yaparken oldukça faydalı. Şimdi daha yakından inceleyelim.

Debugbarın açık olamsı için çalışma ortamının "development" olarak ayarlanması gereklidir.

debugbar-light

Genel görünümü yukarıdaki gibi. Gördüğünüz üzere veritabanı, viewlar, dosyalar, geçmiş gibi bir çok şey hakkında bilgi veriyor.

Eğer bir sayfayı ziyaret ettiğinizde hangi işlem için ne kadar zaman harcandığını görmek isterseniz ilk menüden bunu yapabilirsiniz. Aşağıdaki örnekte frameworkün ne kadar sürede çalışmaya başladığını (bootstrap), yönlendirme işlemi (routing) süresini, veritabanı işlemleri süresini, view hazırlama süresini ve daha fazlasını oldukça şık bir şekilde görebilirsiniz.

debugbar-light

Database sekmesinde o sayfa için çalıştırılan veritabanı sorgularını görebilirsiniz. Aşağıdaki örnekte sayfanın yüklenmesi için 2 sql sorgusu çalıştırılmış.

debugbar-light

Views sekmesine tıkladığınızda sayfayı yüklemek için kullanığınız viewleri oldukça güzel bir şekilde gösteriyor.

debugbar-light

Files sekmesinde framework işlemleri sırasında kullanılan her bir dosyanın listesini görebilirsiniz.

Routes sekmesinde projeniz için tanımlamış olduğunuz her bir yönlendirme (route) kurallarının listesine ulaşabilirsiniz.

Vars sekmesi yüklenen sayfa için kullanılan her bir değişkeni detaylı bir şekilde gösteriyor.

Aynı zamanda debugbar karanlık tema desteğinede sahip.

debugbar-light

Geliştirme işlemlerini oldukça kolaylaştıracak bir çok özelliği barındırıyor ve kendinizde bu bar için özel sekmeler ekleyebilirsiniz.

Routing

Elbetter 4. sürümle beraber routing yapısıda değişti ve oldukça geliştirildi. Codeigniter'in 3. sürümünde routing dizi (array) içerisinde tanımlanıyordu. Artık routin tanımlamalarını bir nesne yardımıyla yapıyoruz.

Örnek bir route ekleme işlemi şu şekilde.

$routes->get('/ornek', 'Home::ornek');

Bu tanımlama şu manaya geliyor. /ornek urline bir get isteği geldiğinde Home controller'ı içindeki ornek fonksiyonunu çalıştır. Aynı mantıkla diğer http metodları içinde tanımlamalarımız şu şakilde:

$routes->add('url', 'Controller::metod', $secenekler);
$routes->get('url', 'Controller::metod', $secenekler);
$routes->post('url', 'Controller::metod', $secenekler);
$routes->put('url', 'Controller::metod', $secenekler);
$routes->head('url', 'Controller::metod', $secenekler);
$routes->options('url', 'Controller::metod', $secenekler);
$routes->delete('url', 'Controller::metod', $secenekler);
$routes->patch('url', 'Controller::metod', $secenekler);

Routes tanımlamaları yaparken 3. parametreye seçeneklerinizi verebilirsiniz. Mesela yönlendirme tanımlamamıza isim vermek istersek ['as' => 'route_ismi'] şeklinde bir parametre verebilirsiniz. Bu sayede daha fazla özelleştirmeye sahip olacaksınız.

Yeni gelen diğer bir güzellik ise gruplandırma imkanı. group() metodu ile bu işlemi şu şekilde yapabilirsiniz.

$routes->group('auth', ['namespace' => 'User'], function(RouteCollection $routes) {
	$routes->get('login', 'Auth::login', ['as' => 'login']);
	$routes->post('login', 'Auth::attemptLogin');
	$routes->post('change-password', 'Auth::changePassword', ['filter' => 'login']);
});

Bu tanımlama şunları yapıyor.

  1. auth/login endpointine get ve post requestleri için gerekli yönlendirme yanımlamalarını yapıyor.
  2. 'namespace' => 'User' user yanımlaması ile aradığımız controller User isim alanında bulunduğunu gösteriyor.
  3. 'filter' => 'login' ise bu yönlendirme için bir filter gerektiğini gösteriyor. Filet, controller ile routing arasında çalışan bir middleware olarak düşünebiliriz. Bu örnekte kullanıcı giriş yapmadan auth/change-password endpointine gidemez gibi düşünebilirsiniz.

Bunların yanında otomatik yönlendirme işlemini kapatmamıza yarayan bir özellik eklenmiş. Bu özellik 3. sürürmde yoktu. Kullanımı şu şekilde.

$routes->setAutoRoute(false);

Daha detaylı bilgiye şuradan ulaşabilirsiniz: CI4 URI Routing

Bitirirken

Elimden geldiğince Codeigniter 4 ile gelen yenilikleri anlatmaya çalıştım. Burada saydığım yenilikler gelen bütün yenilikleden sade birkaçı. Tüm yenilikleri öğrenmek için codeigniter 4 dökümantasyonuna bakmayı unutmayın.

Eğer bir hatam yada yazım yanlışım olduysa bana bildirmekten çekinmeyin.

Tekrar görüşmek üzere …

all tags