كيفية كتابة العناصر القابلة للتكرار الخاصة بك في PHP – CloudSavvy IT
يتيح لك PHP إنشاء كائنات قابلة للتكرار. يمكن استخدام هذه الحلقات الداخلية بدلاً من المصفوفات العددية. عادة ما تستخدم الكائنات القابلة للتكرار كمجموعات من الكائنات. تسمح لك بكتابة الكائن مع الاحتفاظ بدعم الحلقات.
تكرار بسيط
لاجتياز المصفوفة في PHP ، استخدم foreach
حلقة:
foreach (["1", "2", "3"] as $i) echo ($i . " ");
هذا المثال سيصدر 1 2 3
.
يمكنك أيضًا اجتياز كائن:
$cls = new StdClass(); $cls -> foo = "bar"; foreach ($cls as $i) echo $i;
هذا المثال سيصدر bar
.
مشكلة الجمع
للطبقات الأساسية ذات الملكية العامة ، foreach
نتائج جيدة. الآن دعونا نفكر في فئة أخرى:
class UserCollection protected array $items = []; public function add(UserDomain $user) : void $this -> items[] = $user; public function containsAnAdmin() : bool return (count(array_filter( $this -> items, fn (UserDomain $i) : bool => $i -> isAdmin() )) > 0);
هذه الفئة تمثل مجموعة من UserDomain
مثال. نظرًا لأن PHP لا تدعم المصفوفات المكتوبة ، يجب عليك استخدام هذه الفئة عندما تريد مطالبة مصفوفة تحتوي على نوع واحد فقط من القيمة.يمكن أن تساعدك المجموعات أيضًا في إنشاء طرق أدوات مساعدة ، مثل containsWithAdmin
لتسهيل التفاعل الطبيعي مع عناصر المصفوفة.
لسوء الحظ ، فإن محاولة اجتياز هذه المجموعة لن تحقق النتيجة المرجوة.من الناحية المثالية ، يجب أن يكون التكرار $items
المصفوفة ، وليس الصنف نفسه.
تنفيذ المكرر
يمكن استخدام Iterator
واجهه المستخدم.من خلال التنفيذ Iterator
، يمكنك تحديد مثيل الفئة باستخدام foreach
.
Iterator
هناك خمس طرق يجب تنفيذها:
current() : mixed
-احصل على العنصر في الموضع الحالي في التكرار.key() : scalar
-احصل على مفتاح الموقف الحالي في التكرار.next() : void
– الانتقال إلى الموضع التالي في التكرار.rewind() : void
– ترجيع الموضع إلى بداية التكرار.valid() : bool
– معرفة ما إذا كان الموقف الحالي له قيمة.
قد تسبب هذه الأساليب الارتباك في البداية.ومع ذلك ، فمن السهل تنفيذه – عليك تحديد ما يجب القيام به في كل مرحلة foreach
تم تنفيذها.
استخدم مع الكائن الخاص بك في كل مرة foreach
و rewind()
وسوف يطلق.هذه valid()
بعد ذلك ، اتصل بالطريقة لإعلام PHP بوجود قيمة في الموضع الحالي. إذا كان هناك، current()
مع key()
يتم استدعاؤه للحصول على قيمة ومفتاح الموقع. أخيرا، next()
قم باستدعاء الطريقة لتقدم مؤشر الموضع.العودة إلى الاتصال valid()
انظر إذا كانت هناك منتجات أخرى متاحة.
هذا هو تنفيذ نموذجي Iterator
:
class DemoIterator protected int $position = 0; protected array $items = ["cloud", "savvy"]; public function rewind() : void echo "Rewinding"; $this -> position = 0; public function current() : string echo "Current"; return $this -> items[$this -> position]; public function key() : int echo "Key"; return $this -> position; public function next() : void echo "Next"; ++$this -> position; public function valid() : void echo "Valid"; return isset($this -> items[$this -> position]);
هذا ما يحدث أثناء التكرار DemoIterator
:
$i = new DemoIterator(); foreach ($i as $key => $value) echo "$key $value"; // EMITS: // // Rewind // Valid Current Key // 0 cloud // Next // // Valid Current Key // 1 savvy // Next // // Valid
يحتاج مكررك إلى الاحتفاظ بسجل لموضع الحلقة ، والتحقق مما إذا كان هناك عنصر في موضع الحلقة الحالي (تمرير valid()
) ، ثم قم بإرجاع المفتاح والقيمة في الموضع الحالي.
عندما يكون موضع الحلقة غير صالح ، لن تحاول PHP الوصول إلى المفتاح أو القيمة.إرجاع false
من valid()
الإنهاء على الفور foreach
حلقة. عادة ، سيكون هذا هو الوقت الذي تصل فيه إلى نهاية المصفوفة.
التكرار
يمكن أن تصبح مُكررات الكتابة متكررة بسرعة. معظمهم يتبعون الوصفة الدقيقة الموضحة أعلاه. IteratorAggregate
إنها واجهة تساعدك على إنشاء كائنات متكررة بسرعة.
ينفذ getIterator()
الطريقة والعودة أ Traversable
(الواجهة الأساسية Iterator
).عند استخدام الكائن الخاص بك مع العناصر التالية ، سيتم استخدامه كمكرر foreach
. عادةً ما تكون هذه هي أسهل طريقة لإضافة التكرار إلى فئة المجموعة:
class UserCollection implements IteratorAggregate protected array $items = []; public function add(UserDomain $User) : void $this -> items[] = $user; public function getIterator() : Traversable return new ArrayIterator($this -> items); $users = new UserCollection(); $users -> add(new UserDomain("James")); $users -> add(new UserDomain("Demo")); foreach ($users as $user) echo $user -> Name;
عند العمل مع المجموعات ، عادة ما تحتاج فقط إلى ثلاثة أسطر من التعليمات البرمجية لإعداد التكرار!واحد ArrayIterator
كعائد Traversable
.هذا هو الذي سينشئ واحدًا تلقائيًا Iterator
خارج المصفوفة. الآن ، يمكنك اجتياز القيم المنطقية داخل الكائن بدلاً من الخصائص المباشرة للكائن.
استخدام مكررات PHP سابقة الإنشاء
إذا كان لديك منطق معقد ، فأنت بحاجة إلى كتابة مكرر خاص بك. نظرًا لأن PHP تأتي مع العديد من أدوات التكرار المتقدمة التي توفرها SPL ، فلا داعي تقريبًا للبدء من الصفر.
تتضمن الفصول المضمنة DirectoryIterator
و FilesystemIterator
و GlobIterator
ومختلف التكرارات العودية. هذه بعض من أكثر التكرارات العامة فائدة.
المغير
هذه LimitIterator
يسمح لك باجتياز مجموعة فرعية من المصفوفة.لا تحتاج إلى تجميع المصفوفات أولاً ، ولا تحتاج إلى تتبع المواضع الداخلية يدويًا foreach
.
$arr = new ArrayIterator(["a", "b", "c", "d"]); foreach (new LimitIterator($arr, 0, 2) as $val) echo $val;
هذا المثال سيصدر a b
.ملاحظة LimitIterator
تقبل آخر Iterator
بدلا من المصفوفة.يستخدم هذا المثال ArrayIterator
، إنها فئة مدمجة Iterator
من المصفوفة.
مكرر لانهائي
InfiniteIterator
لا تنهي الحلقة أبدًا ، لذلك أنت بحاجة break
يدويا منه. خلاف ذلك ، سوف يلتف المكرر تلقائيًا إلى بداية المصفوفة عندما تصل إلى نهاية المصفوفة.
هذا المكرر مفيد بشكل خاص عند استخدام القيم المستندة إلى الوقت.هذه طريقة بسيطة لإنشاء تقويم مدته ثلاث سنوات ، والذي يستخدم أيضًا LimitIterator
كما ذكر أعلاه:
$months = [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ]; $infinite = new InfiniteIterator(new ArrayIterator($months)); foreach (new LimitIterator($infinite, 0, 36) as $month) echo $month;
استغرق هذا ثلاث سنوات.
عامل التصفية
FilterIterator
إنها فئة مجردة يجب تمديدها.ينفذ accept
طريقة لتصفية القيم غير المرغوب فيها ، والتي سيتم تخطيها أثناء التكرار.
class DemoFilterIterator extends FilterIterator public function __construct() parent::__construct(new ArrayIterator([1, 10, 4, 6, 3])); public function accept() return ($this -> getInnerIterator() -> current() < 5); $demo = new DemoFilterIterator(); foreach ($demo as $val) echo $val;
هذا المثال سيصدر 1 4 3
.
سيتم تصفية قيم الصفيف الأكبر من 5 ولن تظهر في foreach
.
نوع “قابل للتكرار”
في بعض الأحيان قد تكتب وتستخدم foreach
حلقة ، لكن لا تعرف شيئًا عن القيمة التي سيتم تكرارها. مثال على ذلك هو معالج الخطأ المجرد ، والذي يقوم فقط بتفريغ القيمة المستلمة.
يمكنك إدخال تلميح iterable
في هذه الحالات.هذا نوع زائف ، سيقبل array
أو أي كائن محقق Traversable
:
function handleBadValues(iterable $values) : void foreach ($values as $value) var_dump($value);
هذه iterable
النوع غامض للغاية ، يجب عليك التفكير فيه بعناية قبل الاستخدام.ومع ذلك ، إذا كنت بحاجة إلى التأكد من أن قيمة الإدخال يمكن أن تكون foreach
.
ختاما
يمكن أن يساعدك استخدام التكرارات في كتابة المزيد من التعليمات البرمجية المعيارية والنظيفة. يمكنك نقل الطرق التي تعمل على مصفوفة الكائن إلى فئة مجموعة مخصصة.يمكن بعد ذلك كتابة هذه الكلمات بشكل منفصل مع الاحتفاظ بها foreach
.
في معظم الحالات ، يمكنك تنفيذ IteratorAggregate
ثم العودة ArrayIterator
تكوين العناصر في مجموعتك. يمكن لأنواع مكررات PHP الأخرى (التي لا يستخدمها المطورون عادةً) تبسيط الحلقات الأكثر تحديدًا.إنها توفر سلوكًا منطقيًا معقدًا دون مطالبتك بتتبع المؤشر يدويًا foreach
بيان.