Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:64394 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 79265 invoked from network); 21 Dec 2012 00:05:57 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 21 Dec 2012 00:05:57 -0000 Authentication-Results: pb1.pair.com header.from=davidkmuir@gmail.com; sender-id=pass Authentication-Results: pb1.pair.com smtp.mail=davidkmuir@gmail.com; spf=pass; sender-id=pass Received-SPF: pass (pb1.pair.com: domain gmail.com designates 209.85.210.43 as permitted sender) X-PHP-List-Original-Sender: davidkmuir@gmail.com X-Host-Fingerprint: 209.85.210.43 mail-da0-f43.google.com Received: from [209.85.210.43] ([209.85.210.43:57355] helo=mail-da0-f43.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id C5/9F-20281-4E7A3D05 for ; Thu, 20 Dec 2012 19:05:57 -0500 Received: by mail-da0-f43.google.com with SMTP id u36so1771421dak.2 for ; Thu, 20 Dec 2012 16:05:53 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=x-received:message-id:date:from:user-agent:mime-version:to:cc :subject:references:in-reply-to:content-type :content-transfer-encoding; bh=KlfK/onMdnCyKHEfY0dPzkt6fhKbeQB7QPJnkIc0JDg=; b=AtjNmIRKumGqU/81zFkDcqvmtT3CKQvM3WB6IUn2EKpKDlmcccnH2/X7svNgBUjDyf pbTgrMU66r1PexOs4xb1vIX7sHyab88gchL1i28E1y2FtzZ3cWt+d5B9KFUbNNPtuJXI uAs7byhOUQBMnCpWpG9FUkqKo8tv6K1P9hZMxCnjwelBpGvqrXPJnagCd36w1NTLjWxD +bb2rcheyfwIbgAwuIpKZFywar0nya/m4el2UnJzTywgdYzZmd6YjQbRgv1ho9Ir0URP h0hWVPnLHtNv7+oCr+Rvv0LPep5gts+jzZ83TPKzUPyfthL8inmLNul4O/9iYRX/JFZu fYzA== X-Received: by 10.68.190.227 with SMTP id gt3mr34828626pbc.5.1356048353903; Thu, 20 Dec 2012 16:05:53 -0800 (PST) Received: from [192.168.1.181] (tmwpho1.lnk.telstra.net. [110.142.207.74]) by mx.google.com with ESMTPS id ay5sm6226562pab.1.2012.12.20.16.05.50 (version=SSLv3 cipher=OTHER); Thu, 20 Dec 2012 16:05:53 -0800 (PST) Message-ID: <50D3A7DC.6070402@gmail.com> Date: Fri, 21 Dec 2012 11:05:48 +1100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:17.0) Gecko/17.0 Thunderbird/17.0 MIME-Version: 1.0 To: Christopher Jones CC: internals@lists.php.net References: <50D05CD0.8080206@php.net> <50D06E8B.9020807@php.net> <50D24B4C.4070901@garfieldtech.com> <50D29483.20802@oracle.com> <50D33D6B.4060404@garfieldtech.com> <50D3A06F.5000608@oracle.com> In-Reply-To: <50D3A06F.5000608@oracle.com> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Subject: Re: [PHP-DEV] Extension for str_replace / preg_replace with arrays From: davidkmuir@gmail.com (David Muir) On 21/12/12 10:34, Christopher Jones wrote: > > > On 12/20/2012 08:31 AM, Larry Garfield wrote: >> On 12/19/12 10:30 PM, Christopher Jones wrote: >>> >>> >>> On 12/19/2012 03:18 PM, Larry Garfield wrote: >>>> You could likely simplify the code even further using an infinite >>>> iterator: >>>> >>>> http://us1.php.net/infiniteiterator >>>> >>>> $result = preg_replace_callback( >>>> '/word/', >>>> function($matches) use (&$replacements_iterator) { >>>> return $replacements->next(); >>>> }, >>>> 'word word word word word' >>>> ); >>>> >>>> --Larry Garfield >>>> >>> >>> What am I missing that causes the first call to >>> $replacements_iterator->current() to return NULL >>> unless the iterator is rewound before use? >> >> Eh, nothing. You're right, next() doesn't return an element, it just >> advances, so you still need the current() call. Which seems kinda >> silly to me, but whatev. > > That is documented, so it's OK. The curiosity (bug?) is the need to > call rewind(): > > $replacements_iterator = new InfiniteIterator(new > ArrayIterator($replacements)); > $replacements_iterator->rewind(); // why is the rewind needed? > > $result = preg_replace_callback( > '/word/', > function($matches) use ($replacements_iterator) { > $r = $replacements_iterator->current(); > $replacements_iterator->next(); > return $r; > }, > 'word word word word word word word word' > ); > > In other (simple) scripts using InfiniteIterator the rewind wasn't > needed. > > What happens if you do: $replacements_iterator = new InfiniteIterator(new ArrayIterator($replacements)); var_dump($replacements_iterator->current()); If I remember correctly, when you pass a traversable into foreach, under the hood, it basically calls: $iterator->rewind(); while($iterator->valid()){ $value = $iterator->current(); ....(foreach block).... $iterator->next(); } So that might explain why it works in "(simple) scripts". It does seem like a bug that the rewind is required though. A newly created iterator should already be in a rewound state so the call shouldn't be needed. Cheers, David