السلام عليكم ورحمة الله وبركاته ..
إهداءً للأخ أحمد أبو السعود والأخ عبد اللطيف عرفانا لهما بالجميل ..فقد تعلمت php حقيقة من خلال دروسهما في دورة (لنبدأ مع PHP )
أقدّم هذا البرنامج ... كتابة خريطة على هيئة شجرة وتحويلها إلى ترميز JSON .
فكرة البرنامج :
نحتاج في كثير من التطبيقات إلى تشكيل شجرة من البيانات ..
مثلاً لنفترض أننا نصنّف الدول ..
هناك دول آسيوية ودول افريقية ..
والدول الآسيوية تحوي دول عربية ..
والدول العربية الآسيوية تحوي دول المتوسط ودول الخليج ودول البحر الأحمر ..
وهنا يمكننا الاعتماد على الترميز التالي (فكرته بسيطة جدا من تصميمي :P )
1- نبدأ بالجذر بكتابة اسم الجذر دون أي فراغ قبله..
2- اذا اردنا أن نتفرّع عن الفرع الحالي نضيف فراغا قبل كتابة اسم الفرع ..
3- اذا اردنا اغلاق الفرع الحالي والعودة الى جذره أو جذر جذره ..الخ .. فقط ننقص عدد الفراغات السابقة للاسم بحيث يتساوى مع عدد فراغات الفرع الذي نريد ان نكون فيه .
(ملاحظة : جميع الحقوق محفوظة :D )
لنبدأ بمثال بسيط :
مثال
مثال برمجي
لغات البرمجة
C
C++
Php
والمزيد
مثال حقيقي
مشرفو الفريق العربي
أحمد
أحمد سعود
أحمد أبو عبد البر
حسام
حسام الشامي
المزيديوضّح المثال السابق الآلية البسيطة جدا لتمثيل شجرة (بالفراغات السابقة للاسم )
وكما ترون يمكننا تمثيل الكثير من البنى بشكل شجرة كالفهارس مثلا ..
جاءت الفكرة عندما احتاج احدهم ان يكون الترميز السابق مفهوما من قبل لغات البرمجة ..
ووقع الاختيار على JSON بدون سبب :D
والآن إليكم الكود :
والذي يقوم بقراءة محتويات ملف ما .. مكتوبة بالصيغة المبتكرة السابقة .. ثم يحول البنية كاملة إلى تنسيق JSON ..
طبعا كالعادة الكود يحتاج التطوير والتنقيح والتحسين والتسريع الخ الخ ... ولكن لن أنتظر اكتماله ... فالكمال لله .. والتحسين على كواهلكم أيها الأخوة الأكارم :)
الكود مشروح سطرا سطرا ....(حسب الطريقة التي اتبعها أخي أحمد أبو السعود في أول مشاركة تعرفت عليه بها :) )
أرجو أن يكون فيه النفع والفائدة للجميع .. وارجو أن يكون فيه رد ولو بسيط لما قدّمه الأخوة أحمد أبو السعود والأخ عبد اللطيف في دورة الphp الرائعة :)
<!--
//ملاحظة حتى لا يحدث خلط بين العربي والأجنبي قد أكتب كلمات انكليزية بالعربي مثل جيسن أو بي اتش بي .. رغم أني أكره فعل ذلك
--!>
<?php//بداية الكود
$output="";//متحول الخرج : ويحتفظ بكل ما سنطبعه لا حقا
function Print_($a)//دالة الطباعة وتأخذ وسيطا النص المراد طباعته
{// بداية جسم الدالة
global $output;//الاشارة الى اننا سنستعمل متحول الخرج الموجود خارج الدالة
echo $a;//طباعة النص على المتصفح
$output.=$a;//وحفظ النص في المتحول
}//نهاية جسم الدالة
$Rhandler=fopen("1.txt",'r');//فتح الملف والقراءة منه وحفظ المقبض في متحول
$llevel=0;//متحول يحفظ عمق آخر فرع مررنا عليه
//كلمة عمق أعني بها مقدار التفرع داخل الشجرة
Print_("{");//طباعة بداية نص الجيسن
$x=false;//متحول يستعمل مرة واحدة لمنع كتابة الفاصلة في بداية الملف (أرجو التحسين ) وشكرا
for($i=0;//حلقة
!feof($Rhandler);//طالما لم نصل لنهاية المف الذي نقرأ
$i++,//ملاحظة : هذا المتحول ليس له أي عمل
$llevel=$clevel)//عند نهاية كل دورة نحفظ العمق الحالي في المتحول الدال على آخر عمق مررنا عليه
//l = last
//c = current
{//بدء الحلقة
$content=fgets($Rhandler);//قراة سطر وحيد من الملف وحفظه في متحول
for($clevel=0;$content[$clevel]==' ';$clevel++);//حلقة تعد الفراغات في بداية الاسم
//عدد الفراغات هو نفسه عمق الفرع في الشجرة
//الاسم يحتوي فراغات في بدايته ورموز نهاية السطر في نهايته لذلك سنقوم بازالتها
$buffer="";//المتحول الذي سنحفظ فيه الاسم بعد التعديل
for($i=$clevel;$i<strlen($content)&&$content[$i]!="\r"&&$content[$i]!="\n";$i++)
$buffer.=$content[$i];//نأخذ حرفا حرفا من السطر حتى نصل الى نهايته دون أخذ محارف نهاية السطر
$content=$buffer;//نعيد حفظ المحتوى في المتحول القديم
//سنبدأ بخوارزمية التحول إلى جيسن
if($clevel==$llevel)//في حال كان العمق الحالي هو نفس العمق السابق
{//فهذا يعني أننا في نفس المصفوفة وعلينا اضافة عنصر فقط
if($x)//محقق من اجل جميع العناصر عدا أول جذر أي عند بداء الملف فقط
{
Print_(":\"info\"");//نضع أي محتويات تخص العنصر حتى لا نتركه بدون محتوى فنحن في حاوية ترابطية تحفظ الاسم وتحفظ المحتوى معا
Print_(",\"$content\"");//ثم نضع فاصلة ونطبع امحتوى السطر
}
else
{
Print_("\"$content\"");//نفس الكلام السابق ولكن بدون فاصلة البدء
$x=true;//حتى لا ندخل الى هنا ثانية
}
}
else if($clevel<$llevel)//حالة الخروج من الفرع الى مستوى سابق
{
Print_(":\"info\"");//نطبع اي محتوى لآخر فرع كنا فيه
for($k=$clevel;$k<$llevel;$k++)
Print_("}");//لقة تقوم بإغلاق الأقواس بنفس كمية الفرق بين المستويين
Print_(",\"$content\"");//ثم نطبع محتوى السطر بعد الفاصلة بعد أن وصلنا الى المستوى المطلوب
}
else//حالة انشاء فرع جديد
{
Print_(":{\"$content\"");//نضع نقطتين للدلالة على وجود محتوى للفرع الحالي وأول عنصر فيه هو المحتوى الحالي
}
}//عند الخروج من الحقة يكون الملف قد انتهى
Print_(":\"info\"");//نضع أي محتوى لآخر فرع كنا فيه
for($k=0;$k<$llevel;$k++)
Print_("}");//ونغلق كل الاقواس المفتوحة
Print_("}");//ونغلق قوس البداية
fclose($Rhandler);//ونغلق الملف
//والآن للتأكد سنقوم بالتحويل والتحويل العكسي للتأكد أن التنسيق صحيح والمفترض طباعة كل ما تم طباعته ساقبا مرة أخرى بتطابق تام
echo "</BR>\n".json_encode(json_decode($output));
?>//نهاية الكود
//الحمد لله على فضله ونعمائه
//أخوكم مصطفى(أرجو من الله ألا يتم استعمال البرنامج لأي غرض لا يرضيه بأي شكل . وأن يكون استخدامه لخير المسلمين في اي مكان ... وهو ولي التوفيق)
والسلام عليكم ورحمة الله وبركاته ...
(ملاحظة : أرجو عدم كتابة ردود تحتوي على عبارات الشكر فقط ... فليس فيها نفع لمن سيقرأ المشاركة من بعدك .. بل حاول الإفادة بملاحظة على الكود أو بتحسين أو تطوير أو اقتراح أو فكرة جديدة .. وجزاك الله خيرا )