Lesson 2 / الدرس 2
The things that differ, and the things nobody may see / ما يختلف، وما لا يجوز أن يراه أحد
Two kinds of value cannot live in your code: what changes between environments, and what must never be published. They are handled the same way, and the day you get it wrong is the day a password is in a public repository forever.
نوعان من القيم لا يمكن أن يعيشا في كودك: ما يتغير بين البيئات، وما لا يجوز نشره أبدًا. ويُعالجان بالطريقة نفسها، ويوم تخطئ فيهما هو يوم تصير كلمة سر في مستودع عام إلى الأبد.
A database password, an API key, the address of a mail server, whether debugging is on: none of these belong in a file you commit. The code is the same everywhere; the configuration is what makes one copy of it your machine and another copy the live site. Keep them separate and deploying becomes copying code, nothing more.
A file, ignored by git, with an example beside it
config.php <- real values. In .gitignore. Never committed.
config.example.php <- the same keys, with placeholder values.
COMMITTED, so a new developer knows what
the application needs without asking.
# .gitignore
/config.php
/storage/logs/
/storage/uploads/
<?php
// config.example.php — committed, and readable as documentation.
return [
'debug' => true,
'db' => [
'host' => '127.0.0.1',
'name' => 'training',
'user' => 'CHANGE_ME',
'password' => 'CHANGE_ME',
],
];
// And in the application: fail loudly on a missing setting rather than
// defaulting to something that half works.
$config = require __DIR__ . '/../config.php';
foreach (['db.host', 'db.name', 'db.user', 'db.password'] as $key) {
if (config($key) === null) {
throw new RuntimeException("config: {$key} is not set");
}
}
What to do when a secret gets out
-
Change the secret first. Before cleaning anything up, before telling anyone, before working out how it happened. A rotated key makes the leak harmless; everything else is tidying. غيّر السر أولًا. قبل تنظيف أي شيء، وقبل إخبار أحد، وقبل معرفة كيف حدث. فالمفتاح المغيَّر يجعل التسريب غير ضار؛ وكل ما عداه ترتيب.
-
Assume it was read. Public repositories are scanned continuously by automated tools; a key pushed and deleted four minutes later has been collected. Plan for used, not for probably-fine. وافترض أنه قُرئ. فالمستودعات العامة تُمسح باستمرار بأدوات آلية؛ والمفتاح المدفوع والمحذوف بعد أربع دقائق قد جُمع. خطّط لأنه استُخدم، لا لأنه على الأرجح بخير.
-
Tell whoever needs to know, the same day. A leaked credential is not an embarrassment to manage quietly — it is an incident, and the cost of naming it early is always smaller than the cost of it being found later. وأخبر من يلزم إخباره في اليوم نفسه. فبيانات الاعتماد المسرَّبة ليست إحراجًا يُدار بهدوء — بل حادث، وتكلفة تسميته مبكرًا أصغر دائمًا من تكلفة اكتشافه لاحقًا.
-
Then fix the history, knowing it changes nothing about the exposure. Rewriting git history breaks everyone's clone and does not reach forks, caches or anyone who already pulled. ثم أصلح التاريخ، عالمًا أنه لا يغيّر شيئًا في الانكشاف. فإعادة كتابة تاريخ git تكسر نسخ الجميع ولا تبلغ التفرعات ولا الذواكر ولا من سحب أصلًا.
config.php داخل public/، فسوءُ ضبطٍ واحد للخادم — تكفّ PHP عن التنفيذ فتُقدَّم الملفات نصًّا — ينشر كلمة سر قاعدة بياناتك على رابط يستطيع أي أحد تخمينه. وقد حدث ذلك لشركات كبيرة، والعلاج مستوى مجلد واحد. وهذا الموقع يحفظ الضبط فوق public/ بمستوى لهذا السبب بعينه.Check yourself / اختبر نفسك
1. What is config.example.php for?
Without it the next person discovers each required setting by hitting the error it causes. The example file is the difference between configuration and folklore.
2. A key was pushed to a public repository and deleted four minutes later. What now?
Rotation is what makes the leak harmless; everything else is tidying. Rewriting history does not reach forks, caches or anyone who already pulled.
3. Why crash on a missing configuration value rather than defaulting?
A crash on the first request is a cheap, obvious failure. A site that half works is discovered weeks later by someone who did not receive an email.
Score / النتيجة: 0 / 3