Skip to content

I have a cure for the “Eli Travel Curse”

Dear Reader,

IMG_0370If you are a speaker in the PHP community, you know about “The Eli Travel Curse”. For everyone else, basically we all know that you never ever travel on the same flight as Eli White. Heck, most of us won’t share a cab with him to the airport, and we get nervous if we see him at an adjacent gate, or even traveling on the same day. :) This makes traveling to PHP conferences tough because Eli is a beloved fixture at most conferences. Dont get me wrong, we all love Eli, but he has the absolute worst luck in traveling.

I’m happy to say that I have a cure for those who are “Eli adjacent” when traveling. The picture above is my magic talisman.

WAIT! Before you realize you recognize what it is and rush out to get yours, this is a special talisman that can’t be simply purchased off the shelf. Yes, this is the talisman that comes on most bottles of Pyrat Rum. However, this particular one is off a bottle of Pyrat rum given to me by Eli himself.

Eli and I share a couple of common points in our job timeline. The first one was that I preceded him as the Editor-in-Chief for Zends DevZone. As a thank you for some small pieces of advice I gave him while he was at Zend, Eli presented me with a bottle of Pyrat Rum at ZendCon 2009; this is the talisman from that bottle. I’ve had this talisman hanging on every backpack or bag I carry with me since then. I keep it with me to remind me of this important lesson.

No matter who asks you, and no matter how insignificant you think your help is, you have no idea how much or little affect others when you help them. So help everyone you can, as often as you can.

Since I hung this little gift from Eli on my backpack, my travel woes have been cut significantly.

  • I’ve not had a flight canceled
  • I’ve not been stuck in a strange city
  • I’ve only had a handful of flights delayed…way down from pre-talisman days

Now you can attribute all of this to the fact that the airline industry is getting better at service. You can say it’s because I now primarily fly Southwest and they have a very good track record. Me? I know the real answer.

Takeaways

  1. I would have never received my magical talisman if I hadn’t been willing to help a friend when he asked. Since then I’ve learned that it doesn’t have to be a friend, I do my best to help everyone who asks…and a few who don’t.
  2. If you want to be safe in your travels, you gotta get Eli to give you a bottle of rum. :)

Helping people, it cured the Eli travel curse for me! :)

Until Next Time,
I <3 |<
=C=

p.s. Pyrat Rum is now one of my favorite rums of all times. Good stuff if you can find it.

WordPress REJECTED MY PLUGIN!

The Rejection by Andreas WintererDear Reader,

One of the biggest complaints I hear about WordPress is that yes, you can choose from thousands of plugins, but many of them are crap. Because there was no barrier to entry, many of them were poorly coded and could even introduce security vulnerabilities to your site. I recently found out the hard way that WordPress is moving to change that. :)

First, they have been retiring old and unmaintained plugins for a while now. Thankfully, that includes all the plugins I wrote back in the 1.5-1.9 days. :) More importantly though, there is now a code review before accepting new plugins. This is a very good move on their part and I applaud them for this move.

There is a small problem though. They don’t seem to have published anything on what is acceptable/unacceptable in a plugin. In discussing my particular plugin with the reviewer, it seems the rules are kind of fuzzy as to what gets accepted or not, and they seem to be changing.

Overall, I think that a code review process is a very positive move for the WordPress ecosystem. It would be nice however, if the review team published the current rules. Even if those rules change, a current set of rules would help make sure that plugin developers don’t waste time and effort on plugins that won’t be accepted.

If these guidelines are already available, linking to them from “Writing a Plugin” would be apprecaited.

Well done, WordPress!

Until next time,
I <3 |< =C= p.s. I am working on updating my plugin to change the reported problem so that hopefully it will be accepted next time. (fingers crossed) :) Photo Credit: The Rejection by Andreas Winterer. Used under Creative Commons License.

What PHP framework should I learn?

Dear Reader,

I get asked this question every now and then. It recently came up on twitter. To me, this is like a carpenter being asked “Which hammer should I use to build a house?”.

Each of the modern PHP frameworks have their strengths and weaknesses. If you are a professional programmer, you need to be aware of the top frameworks. (No, I won’t define them here, you figure out which ones are important to your particular career) You also need to be able to work in a couple of them. “Knowing of” and “Knowing how to use” are two totally different things.

There is no “right” framework, there is the right one for the job at hand. If you only know how to work with one of them, well, then you can build your house with that particular hammer.

Professional programmers should have a variety of tools in their tool belt. No, you don’t need to know how to work in all the PHP frameworks, but you will need to know 2 or 3 of them. Invest some time in yourself and your skills. Take one weekend a month and build a small project in a framework you know OF but don’t know how to use. See if it is a better tool than the one you are currently using. The worst thing that can happen is that you learn something new.

Until next time,
I <3 |<
=C=

The PHP CachingIterator

Dear Reader,

(Sample code for those too dang lazy to cut ‘n paste)

How I got here

In the course of writing my next book, “Iterating PHP Iterators”, I found something very interesting.

I have a short chapter on the CachingIterator. One of the flags in the CachingIterator is FULL_CACHE. It was during my experiments with tha, that I found…an anomaly.

Note: As of yet, I have not reported this as a bug in PHP because it may just be a situation of “I’m doing it wrong”. I’m putting this out here mainly so someone can point me in the right direction. If no one can, then I’ll file a bug.

The proof of error code

The example I am using in my book is the 7 Dwarfs. Here is the code.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?php
$dwarves = [1=>'Grumpy',
            2=>'Happy',
            3=>'Sleepy', 
            4=>'Bashful', 
            5=>'Sneezy', 
            6=>'Dopey', 
            7=>'Doc'];
$it      = new CachingIterator(new ArrayIterator($dwarves), 
                               CachingIterator::FULL_CACHE);
foreach($it as $v);
 
$it->offsetUnset(4);
$it->offsetSet('Cal','Kathy');
$it[5]='Surly'; 
 
foreach($it as $offset=>$value) {
	echo 'Original: '.$offset.' == '.$value."\n";
}

That code actually works, even if it doesn’t work the way I would expect it to. I would expect that iterating over $it would give me the modified version, not the original “cached” version. Note that Bashful is still in the list and Kathy is not. It is the original list as we loaded it into the ArrayIterator. Also, line 11 is very important, if a bit silly. Yes, you have to spin through the entire array if you pass it in on the constructor, otherwise, the cache doesn’t get loaded.

Now let’s add a little more to it.

1
2
3
foreach($it-&gt;getCache() as $offset=&gt;$value) {
	echo 'Cache: '.$offset.' == '.$value."\n";
}

This now outputs:

$ php ../examples/test.php 
Original: 1 == Grumpy
Original: 2 == Happy
Original: 3 == Sleepy
Original: 4 == Bashful
Original: 5 == Sneezy
Original: 6 == Dopey
Original: 7 == Doc
Cache: 1 == Grumpy
Cache: 2 == Happy
Cache: 3 == Sleepy
Cache: 4 == Bashful
Cache: 5 == Sneezy
Cache: 6 == Dopey
Cache: 7 == Doc

Ok, so now, even when we pull the cache, we still get the original list. I’m not sure how that is right, ever. I know a few of you are saying “but Cal, you have to rewind().” It is to those of you who I say “read my book”. :) But just for grins and giggles, let’s rewind the iterator.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<?php
 
$it = null;
 
$dwarves = [1=>'Grumpy',
            2=>'Happy',
            3=>'Sleepy', 
            4=>'Bashful', 
            5=>'Sneezy', 
            6=>'Dopey', 
            7=>'Doc'];
 
$it      = new CachingIterator(new ArrayIterator($dwarves), 
                               CachingIterator::FULL_CACHE);
foreach($it as $v);
 
$it->offsetUnset(4);
$it->offsetSet('Cal','Kathy');
$it[5]='Surly'; 
 
foreach($it as $offset=>$value) {
	echo 'Original: '.$offset.' == '.$value."\n";
}
 
$it->rewind();
 
foreach($it->getCache() as $offset=>$value) {
	echo 'Cache: '.$offset.' == '.$value."\n";
}
</code>

Now when we run it we get this:

$ php ../examples/test.php 
Original: 1 == Grumpy
Original: 2 == Happy
Original: 3 == Sleepy
Original: 4 == Bashful
Original: 5 == Sneezy
Original: 6 == Dopey
Original: 7 == Doc
Cache: 1 == Grumpy

Hmmm…well that ain’t right.

Here is what DID work. I am not entirely sure why at this point, I’m still investigating.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?php
$dwarves = [1=>'Grumpy',
            2=>'Happy',
            3=>'Sleepy', 
            4=>'Bashful', 
            5=>'Sneezy', 
            6=>'Dopey', 
            7=>'Doc'];
 
$it      = new CachingIterator(new ArrayIterator($dwarves), 
                                   CachingIterator::FULL_CACHE);
foreach($it as $v);
 
$it->offsetUnset(4);
$it->offsetSet('Cal','Kathy');
$it[5]='Surly'; 
 
foreach($it->getCache() as $offset=>$value) {
	echo 'Cache: '.$offset.' == '.$value."\n";
}
 
foreach($it as $offset=>$value) {
	echo 'Original: '.$offset.' == '.$value."\n";
}

Now we are through the looking glass. The order in which the loops appear in your code makes a difference? Technically, this code outputs the list correctly if you ignore the fact that the cache version should be the immutable one and that $it itself should reflect the changes.

$ php ../examples/test.php 
Cache: 1 == Grumpy
Cache: 2 == Happy
Cache: 3 == Sleepy
Cache: 5 == Surly
Cache: 6 == Dopey
Cache: 7 == Doc
Cache: Cal == Kathy
Original: 1 == Grumpy
Original: 2 == Happy
Original: 3 == Sleepy
Original: 4 == Bashful
Original: 5 == Sneezy
Original: 6 == Dopey
Original: 7 == Doc

BONUS ROUND:

Take the above code, now swap the two foreach statements. See what I mean? The order that the foreach statements are executed in should have absolutely no effect on the output. If this is expected behavior then we kinda need to put it in the manual.

Sooooo…TIL. don’t use the FULL_CACHE flag on the CachingIterator. I am not sure what the FULL_CACHE flag is supposed to do, but it doesn’t seem to do anything useful at the moment.

Summary:

So today I learned, don’t use the FULL_CACHE flag on the CachingIterator. I am not sure what the FULL_CACHE flag is supposed to do, but it doesn’t seem to do anything useful at the moment. Also, it can screw things up for you.

Here are 3 takeaways.

  1. The ‘cached’ version of the iterator should be the one that does NOT change. The iterator itself should reflect the changes made.
  2. Calling rewind() should never cause the cache to forget everything except the last element.
  3. If you pass in the ArrayIterator in the constructor, it does not get loaded into the cache, you have to put an empty foreach loop in your code to load the cache.

I hope this helps someone along the way.

Until next time,
I <3 |<
=C=

Signaling PHP

Dear Reader,

PrintI’ve just finished my 3rd book – and my first mini-book – and wanted to tell you about it.

“Signaling PHP” is about using PCNTL signals like SIGINT in PHP command line scripts.

Most of the PHP I write these days is CLI scripts. I really wanted to be able to trap signals in some of my scripts. I struggled with this for a while; I even spent an entire weekend googling and reading only to find out that most of the information out there was either wrong, confusing, or incomplete. I decided that once I figured it out, I was going to put everything I learned together in one place to help others that were struggling with this topic as well.

So it is that I present to you “Signaling PHP”. The book is approximately 30 pages long, and is available in PDF, Kindle, and mobi formats.

You can get your copy by visiting http://signalingphp.com.

Until next time,
I <3 |<
=C=