تكنولوجيا

كيفية كتابة العناصر القابلة للتكرار الخاصة بك في 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 بيان.

مقالات ذات صلة

اترك تعليقاً

لن يتم نشر عنوان بريدك الإلكتروني. الحقول الإلزامية مشار إليها بـ *

زر الذهاب إلى الأعلى