Kod Konvansiyonları
Kod tabanı bilinçli olarak tek bir biçimde yazılır. Buna uyan kod, içinde durduğu dosya gibi okunur; başkasının yazdığını ilan etmez.
Genel Bakış
Bu kuralların çoğu, tersinin gerçek bir arızaya yol açtığı için vardır: varsayılansız okunan bir değer, meşru bir sıfırı yutan doğruluk kontrolü, sorguya ulaşan kaçırılmamış bir girdi.
Bir kurulumun içinde yazdığınız her şey için geçerlidir: modüller, temalar, kanca dinleyicileri ve bunları destekleyen kod.
Referans
Girdi ve Çıktı
Beş yardımcı, normalde uzanacağınız yerleşiklerin önünde durur. Hepsi statiktir ve varsayılanları vardır; okunacak şey ad değil imzadır.
// coremio/classes/Filter.php
public static function init($arg = null, $mod = false, $special = false);
public static function GET($arg = '');
public static function POST($arg = '');
public static function REQUEST($arg = '');
public static function FILES($arg = '');
public static function SERVER($arg = '');
public static function html_clear($arg = null, $allow = '');
public static function route($arg = '', $special = '');
public static function phone($arg = '');
// coremio/classes/Utility.php
public static function jencode($string = '', $flags = 0): string|false;
public static function jdecode($string = '', $mode = false);
public static function strtolower($str, $encode = 'UTF-8');
public static function strtoupper($str, $encode = 'utf8');
public static function AppAdress($prefix = false);
// coremio/classes/Language.php - coremio/classes/LinkGenerator.php
public static function g($key = '', $replaces = [], $slang = ''): string|int|array|bool;
public static function gc($name = '', $replaces = [], $slang = ''): string|int|array|bool;
public static function selected(): string;
public static function admin($route = '', $params = [], $lang = '', $wqs = []): string|bool;
public static function client($route = '', $params = [], $lang = '');
public static function wQS(null|string|bool $url, string|array $params = []): string;
Filter::init, Parametre Parametre
Birinci argüman kaynağı ve anahtarı adlandırır. GET/, POST/, REQUEST/, FILES/ ya da SERVER/ öneki diziyi seçer, sonraki bölü işaretleri dizinin içine yürür. Önek yoksa argüman, temizlenecek düz bir değer sayılır.
$id = Filter::init('POST/id', 'rnumbers'); // $_POST['id'] -> int
$name = Filter::init('POST/user/name', 'hclear'); // $_POST['user']['name']
$op = Filter::init('REQUEST/operation', 'route'); // $_REQUEST['operation']
$ip = Filter::init('SERVER/REMOTE_ADDR', 'ip'); // $_SERVER['REMOTE_ADDR']
$safe = Filter::init($someString, 'hclear'); // öneksiz: elinizdeki değeri temizler
İkinci argüman serbest bir dize değil, kapalı bir sözlüktür. Neyin hayatta kalacağına, hangi tipin döneceğine ve eksik bir anahtarın neye dönüşeceğine o karar verir. Son sütun önemlidir: cevap tek bir değer değildir, tek bir koruma her modu kapsamaz.
| $mod | Hayatta kalan | $special | Eksik anahtar döndürür |
|---|---|---|---|
| verilmedi | değer olduğu gibi | tek başına kullanılır | false |
hclear | etiketler silinir, önce varlıklar çözülür | yok sayılır | '' |
dtext | hclear ile aynı | yok sayılır | '' |
text | etiketler silinir, sonra tırnaklar varlığa çevrilir | yok sayılır | '' |
letters | a-zA-Z ve etkin dilin kendi harfleri | eklenir | '' |
letters_numbers | 0-9a-zA-Z | eklenir | false |
noun | 0-9a-zA-Z, virgül, nokta, boşluk | eklenir | '' |
numbers | rakamlar ve eksi işareti | eklenir | false |
rnumbers | yukarıdakinin int hâli | eklenir | 0 |
amount | rakam, eksi, nokta, virgül; dize kalır | eklenir | '' |
rate | virgül noktaya döner, fazla noktalar atılır, float olur | eklenir | 0.0 |
identity | rakamlar ve eksi işareti | yok sayılır | false |
ip | 0-9a-zA-Z, eksi, nokta, iki nokta | eklenir | false |
email | 0-9a-zA-Z ve @ . + _ - | yok sayılır | '' |
domain | harf, rakam, nokta, eksi; küçük harfe çevrilir | yok sayılır | '' |
folder | 0-9a-zA-Z ve / - _ . | eklenir | '' |
file | 0-9a-zA-Z, dil harfleri ve - _ . | eklenir | '' |
route | 0-9a-zA-Z ve - _ .; önce ../ silinir | eklenir | '' |
password | hiçbir şey silinmez, ham değer döner | yok sayılır | false |
Üçüncü argüman bir varsayılan değer değildir. Modun kurduğu olumsuzlanmış karakter sınıfının içine eklenen bir parçadır. Saydığınız karakterler kadar filtreyi genişletir.
$_POST['name'] = ' <b>Ada</b> Lovelace ';
Filter::init('POST/name', 'letters_numbers'); // 'AdaLovelace'
Filter::init('POST/name', 'letters_numbers', ' '); // ' Ada Lovelace ' boşluk geri girer
Filter::init('POST/name', 'password'); // ' <b>Ada</b> Lovelace ' dokunulmaz
$_POST['rate'] = '1.234,50';
Filter::init('POST/rate', 'amount'); // '1.234,50' dize
Filter::init('POST/rate', 'rate'); // 1234.5 float
Çeviriler ve Bağlantılar
İki yardımcı da bir dosyaya karşı çözülen bir anahtar alır. İkisi de ikinci bir dizi kabul eder ve bu dizi dil kodu değildir.
Çeviride bu dizi düz bir ara-değiştir işlemidir. Anahtarlar, yer tutucuların kayıtlı metinde göründüğü hâlidir, süslü parantezler dahil. Addan hiçbir şey çıkarılmaz.
// Böyle yazılır:
$text = Language::gc('admin/services/cancel-credit-log-desc', ['{service_id}' => 41]);
// '#41 nolu hizmet iptal iadesi'
// coremio/locale/tr/cm/admin/services.php dosyasından okunur:
return [
'cancel-credit-log-desc' => '#{service_id} nolu hizmet iptal iadesi',
];
// gc() bir bileşen dosyasını adresler: coremio/locale/<dil>/cm/ altında <klasör>/<dosya>/<anahtar>.
// g() bir paket dosyasını adresler: coremio/locale/<dil>/ altında <dosya>/<anahtar>.
$hint = Language::g('needs/password-needs-special', ['{characters}' => '! @ # $']);
Bağlantıda ise dizi, bir rota deseninin yer tutucularını sırayla doldurur. Yer tutucusu olmayan bir rota diziyi yola eklemek yerine yok sayar. Sorgu dizesi asla o yuvaya girmez, dördüncü argümandır.
// coremio/locale/tr/admin-routes.php ['url deseni', 'controller yolu']
return ['admin-routes' => [
'services' => ['services', 'services'],
'users-1' => ['users/(?)', 'users/(1)'],
'financial-2' => ['financial/(?)/(?)', 'financial/(1)/(2)'],
]];
LinkGenerator::admin('services'); // {admin}/services
LinkGenerator::admin('services', ['detail', 5]); // {admin}/services (?) yok, argümanlar düşer
LinkGenerator::admin('users-1', ['detail']); // {admin}/users/detail
LinkGenerator::admin('financial-2', ['coupons', 'add']); // {admin}/financial/coupons/add
// Sorgu dizesi dördüncü argümandır; üçüncüsü dildir.
LinkGenerator::admin('users-1', ['detail'], '', ['id' => 42, 'tab' => 'invoices']);
// {admin}/users/detail?id=42&tab=invoices
// Elinizde zaten bir URL varsa wQS() kullanın; ? mi & mi gerektiğini kendisi seçer.
LinkGenerator::wQS($url, ['tab' => 'cards']);
Değer Okuma
Her dizi anahtarını varsayılanla okuyun. Bu savunmacı bir alışkanlık değil, ölçülmüş bir maliyettir. Eksik anahtar uyarı üretir ve hata işleyicisi her uyarıyı bir disk yazımına çevirir.
// Doğru: null-safe ve "0", "1", 0, 1, null hepsinde tutarlı.
if ((int) ($data['enabled'] ?? 0) === 1) { }
$name = $data['name'] ?? '';
$limit = (int) ($data['limit'] ?? 0);
// Yanlış: empty("0") true döner, yani "0" değeri kaybolur.
// if (!empty($data['enabled'])) { }
// Yanlış: gereksiz uzun ve cast'in söylemediği hiçbir şeyi söylemiyor.
// if (isset($data['enabled']) && (int) $data['enabled'] === 1) { }
Kodun Biçimi
| Kural | Yazın | Yazmayın |
|---|---|---|
| Açılış etiketi | <?php, şablonda <?= | kısa açılış etiketi |
| Diziler | [] | array() |
| Varsayılanlar | $x ?? $y | isset($x) ? $x : $y |
| Tek ifade | süslü parantezsiz | tek satır için üç satırlık blok |
| Derin iç içelik | erken return ya da throw | iç içe koşullar |
| İmzalar | parametre ve dönüş tipleri | tipsiz |
| Çok satırlı listeler | sondaki virgül | yok |
| Dizeler | interpolasyon yoksa tek tırnak | her yerde çift tırnak |
| Arrow function | tek ifadede kısa gövde | tek ifadeyi süslü paranteze almak |
Yorumlar
Varsayılan hiç yorum yazmamaktır. Yazmadan önce kodun onsuz okunamaz olup olmadığını sorun. Okunan koda yazılan yorum, zamanla gerçeklikten kopan bir gürültüdür. Gereken yorum neden'i açıklar, asla ne'yi açıklamaz ve İngilizce yazılır.
Üç tür yorumun kodda yeri yoktur. Bir şeyin nereden kopyalandığına dair notlar, geliştirme sürecine ait notlar ve zaten kendini söyleyen bir satırı tekrar eden açıklamalar.
Örnek
Bir operation ve dağıttığı anahtarları karşılayan iki dosya.
public function update(Operation $operation): bool
{
$operation->demo();
$id = Filter::init('POST/id', 'rnumbers');
if (!$id) throw new Exception(Language::gc('admin/example/error-id-required'));
$name = Filter::init('POST/name', 'hclear');
if ($name === '') throw new Exception(Language::gc('admin/example/error-name-required'));
$data = [
'name' => $name,
'enabled' => Filter::init('POST/enabled', 'rnumbers'),
];
// Yeniden denemeler başarısızlık olarak saklanır; güncellenecek bir success kolonu yok.
if (!$this->model->update($id, $data))
throw new Exception(Language::gc('admin/example/error-save-failed', ['{id}' => $id]));
return $operation->output([
'status' => 'successful',
'redirect' => LinkGenerator::admin('users-1', ['detail'], '', ['id' => $id]),
]);
}
// coremio/locale/tr/cm/admin/example.php
return [
'error-id-required' => 'Bir kayıt seçilmelidir.',
'error-name-required' => 'Ad alanı zorunludur.',
'error-save-failed' => '{id} numaralı kayıt kaydedilemedi.',
];
// coremio/locale/tr/admin-routes.php
return ['admin-routes' => [
'users-1' => ['users/(?)', 'users/(1)'],
]];
Tuzaklar
LinkGenerator::admin($route, $params, $lang, $wqs) sorgu dizesini dördüncü sıraya koyar. Üçüncü sıraya yazılan bir dizi sessizce dil koduna dönüşür ve parametreler kaybolur. Statik çeviri yardımcıları değiştirmeleri ikinci, dili üçüncü alır. Arkalarındaki instance metodu ise ikisini ters alır: Language::g($key, $replaces, $slang) karşısında $lang->get($key, $slang, $replaces). Hatırladığınız imzayı değil, çağırdığınız imzayı okuyun.
Moda göre false, '', 0 ya da 0.0 döner, null asla dönmez. Yani filtre çağrısından sonra yazılan ?? $varsayilan ölü koddur ve !== null ile yazılan bir varlık kontrolü her zaman doğrudur. Modun gerçekten döndürdüğü değerle karşılaştırın.
"0" değeri bir ayar, bir adet ya da bir durum için gerçek bir cevaptır ve doğruluk testi onu çöpe atar. Açıkça karşılaştırın ya da cast edip karşılaştırın.
Yerel bir desen bu sayfayla çelişiyorsa genellikle yerel desen kazanır. Tek bir dosyanın içindeki tutarlılık, bir belgeyle tutarlılıktan daha değerlidir.
İlgili Makaleler
Geri bildiriminiz için teşekkürler!
Yukarıda bulamadığınız her şey için destek ekibimiz her zaman yanınızda.