Upgrading to Zend Framework 2: One Week (or so) Review

After a little more than a week since I started the upgrade to ZF, I have to say I am enjoying working with it, although it certainly gave me headaches. Admittedly, most of those headaches were a result of my own questionable coding decisions from the existing ZF1 application. Still, it was a bit frustrating at times.

A big issue I ran into is my dependency on Zend_Registry. I was using this not only to inject the Doctrine entity manager wherever I needed it, but also to inject some other objects that was pretty much needed everywhere I was working. I realized using it in that manner wasn’t the best idea, but it kept my object instantiation and method calls from become multiple lines long. As this class was removed in Zend Framework 2, I had to scramble to find another solution, which meant having to alter my current code.

For the Entity Manager part, I was able to use ZF2′s Service Manager functionality. By creating a service factory for each of my services, I was able to inject the Entity Manager into it upon its set up. So by using Zend’s Service Locator, I’m able to create an instance of my needed service, with the Entity Manager already available.


$customer = $this->getServiceLocator('myproject-customer-service');

Unfortunately, I was never quite able to get another feature of ZF2, the Dependency Injector (Zend\Di) to work. It just isn’t set up to do what I needed it to do, and from documentation it sounds like something that may not be the best for use in production code anyway. For now I’m injecting most of my dependencies the old fashioned way: through either the class constructor or setter methods. If anyone has any suggestions about how to inject a couple of objects that are instantiated upon successful authentication into my code without doing it in every single action in every single controller, I’d much appreciate them.

Beyond that, I’ve also encountered the changes to Zend\Validator and Zend\Config. Neither of which are changed greatly (although Zend\Config requires an external reader for YAML now), and were pretty quick to switch over in my existing code. Beyond a single onDispatch call I’ve yet to really dig into the eventManager, something I’m very interested in learning. As for the other components of ZF2, I’ve yet to deal with them, although I expect to get into Zend\Permissions soon.

Although the switchover hasn’t been as painless as I’d hoped, I’m still glad to be doing it. The things that have caused the most problems have been things that require me to think about the design of my code, and the end result is a stronger application that will be easier to maintain. Some of the code I’m transferring over needs a good refactoring, and I’m glad to have the chance to do that.

Upgrading to Zend Framework 2.0

While working on a project* recently, I made the decision to move it from its current Zend Framework 1.12 base into Zend Framework 2.0. Although there certainly are similarities in much of the code between the two versions, there certainly are differences, primarily in how the overall structure of the framework operates.

After having futzed with it for a couple days, I have to say I respect and see what they are trying to do, and am excited for the potential good that can come from using it. However, I also have to say that it is causing me some headaches trying to figure out how to get my project to use it**. Admittedly, most of my troubles have come because of my own flawed design of the existing project, some of the problems of which should be solved once I get it running in ZF2.

I’m starting to get the hang of the EventManager, which is a completely new thing to Zend Framework (although I have some experience working with it dating back to before ZF2 was released), and am looking forward to using it to its potential. In addition, as much trouble as it may be causing me right now, I’m really excited about the ServiceManager, and Zend\Di. Finding the right balance when it comes to dependency injection has always driven me a bit crazy, and I hope ZF2 will help get rid of some of that craziness.

I’ll be sharing more as I continue diving into ZF2, so stick around. I promise it will be more than just occasional bouts of profuse swearing and sobbing, interrupted by an occasional growl of “I thought I fixed this?!?”

*What project, you (hypothetical readers) ask? Well…stayed tuned and be patient. All will be revealed in its time.
**It doesn’t help when I introduce my own problems, such as not checking when I copy code that the line numbers in the copied code are removed. I sat there for four hours crawling through ZF2 code trying to find out why the numbers 3-17 were being output, only to discover them in a config file that I should have checked in the first place. The staggering amount of time wasted on this stupid situation would have been prevented if I had followed two of my Rules of Troubleshooting. But more on that in a later post.

DatePeriod Class in PHP: Where were you ten years ago?

In my earlier days of web programming, one of the most frustrating issues that kept coming up was dealing with recurring dates. Trying to get it all put together would take a lot of time and effort. Part of this was because I was a pretty crappy programmer, but also because dealing with dates in PHP used to be a pain in the ass.

Since the advent of \DateTime and its pals \DateInterval and \DatePeriod, it has become much easier to handle dates and times*. All the tricky conversions and formatting headaches have been encapsulated into those objects and their constituent methods. Need to subtract a year from a date? Need to change format of a date string from m/d/Y to d/m/Y or Y-m-d? Need to create a range of dates for the first and fourth Thursday of every month for the next six months? All can be done quickly and easily with the aforementioned classes.

Although I’ve become quite familiar with \DateTime, and have used \DateInterval on many occasions, I wasn’t aware \DatePeriod existed. This is the one that really seems cool to me, as it takes your start date (and end date, if desired), a given interval, and creates an iterator that has every date as determined by the interval in between.

Kids these days don’t know how easy they’ve got it, what with Virtual Machines and phpUnits and DateTimes and whatnots.

*Honestly, it became much easier even before then, once strtotime() came into being. Again, as I was kind of a bad programmer back then, it still took me a couple years before I discovered that function.

Doh! I knew I missed something…

Aside

So I was sitting here trying to figure out why in the heck a simple Doctrine Repository::findOneBy call was not working. The code should work as is, and similar things were working in other places. I toyed around with it, changing things here and there. Still no result. I had the right value to find by, was in the right place, and had the right code. Nope, no result. As I started to panic, it dawned upon me…

I had not put any data in the table yet.

/facepalm

Counting values in an array

While interviewing for a job a couple weeks ago, I was asked to write code in my language of choice (PHP for me, of course) code that would count the number of values in an array, and then display the counts in a list. The first way I did it was a bit over complicated, and would totally not be scalable. I amended it somewhat and made it a bit nicer to use for big arrays, but at one point I suggested there might be a native PHP function that could do this, at least on a one dimensional array. The person interviewing me thought otherwise, and as I was neither in front of a computer nor sure of the existence of this function, I didn’t push the case.

Thinking more about it, I went searching for this function that would have made my solution easier, and lo and behold it exists. The function is array_count_values() and apparently it has existed since PHP4. I’m not sure why I’ve never run into an occasion to use this, although I can recollect a couple of situations (not counting the interview) where this might have been useful.

Just goes to show there is always more to learn, even when you’ve become very familiar with a language.

User Agent Switcher for FireFox

Aside

When adding mobile detection scripts to a website I have found that its much quicker to add all of the different user agent headers we test against to a nice little FireFox plugin called Agent Switcher. I’ve added this to my FireFox toolbar and can quickly test redirection scripts against iPhone, iPad, Andoid and anything else I want to add.

https://addons.mozilla.org/en-US/firefox/addon/user-agent-switcher/developers

Microsoft posts first quarterly loss…ever.

So, I guess July 19, 2012 was a historic, if ignominious, day for Microsoft. It’s kind of amazing that they went 26 years without a loss in even one quarter. I guess it’s not surprising, considering the domination of Windows and Office.

It looks like the rest of their business is still pretty healthy, it was just dragged down by aQuantitive. Apparently that is its competitor to Google’s ad business. Frankly, I’ve never heard of it, even though they’ve owned it for five years. I’m guessing a lot of other people haven’t heard of it either, which would explain why it wasn’t so profitable.

I’m going to imagine this was payback for IE 6 instead.

Remembering my One ZendCon Trip

Yosemite Valley. I like this picture better than the one of the San Jose Convention Center.
In my decade plus as a programmer, I’ve only ever been to one conference, ZendCon 2009. It wasn’t because I didn’t have a desire to go to any, it was a matter of availability and finances. Every company I’ve had the pleasure to work with has found it unnecessary to send its employees to conferences, and I’ve only had the time and money to do it on my own that one time.*

On the whole I enjoyed the experience, although I wish I could say I took away more from it. The big thing at that ZendCon was the big move towards the cloud, which I must admit I was not at all versed on at the time. As such, far too much of the presentations, including the keynote, were Greek to me. Still, it was a interesting four days.

I guess my favorite part was being around some of the major people in the world of PHP. I think I got just a bit too much thrill from listening to some of the “celebrities” of this world.

“Hey, look over there, it’s Matthew Weier O’Phinney! OMG, is that Sebastian Bergmann? IT IS! HOLY SHIT, ANDI GUTMANS IS SITTING IN THE ROW IN FRONT OF ME !!!!!11!111! This is almost as cool as the time I saw Ray Park in the P.F. Changs!”

OK, maybe it wasn’t quite like that, but it was still neat to here these guys who worked on these things that are a crucial part of my job. I regret not actually trying to talk to some of them, if only to better justify the friggin cost of the thing.

Because my brother was with me, for the most part we did our own thing after the presentations and discussions ended in the afternoon. I regret not trying to interact more with the rest of the people there, a pretty general failing for me. At the very least I could have gotten some new insights that could have been helpful. Or at least an invite to the party Microsoft supposedly had where they gave away copies of Windows 7.

Because I was a ZCE I got a discount of about 10% on the whole thing, as well as was invited to an awkward lunch for other ZCE where your regional “representative” tried to make awkward small talk with you at the table. Perhaps the lunch wasn’t as awkward as I remember it, and I was the awkward one (most likely). Still, it isn’t exactly the fondest memory I have.

Recently I got an email telling me to hurry up and sign up for ZendCon 2012 before the early signup discount goes away. Of course even with the discount my currently free-lancer ass can’t afford going, even before expenses such as travel, food, and lodging are factored in. I’ve heard ZendCon is targeted more towards managers anyway, and have thought about looking into going to other conferences. Unfortunately, when they are in Chicago I seemed to be in Virginia or Tennessee, and when they are in Atlanta, I am back in Illinois. I’ve even thought about trying to put a presentation together, but haven’t yet due to the fact I’m not sure I have anything to say that it worth much.

Still, the idea of conventions and conferences is one I can’t shake. Ideally, these are places where the best in the business get together and pick each others brains, often over a nice cold beer or two. If I want to excel in the art of programming, how better to learn than to be around the best? Perhaps some day sooner rather than later I can find out again. And this time maybe I’ll talk to a few more people.

* In addition to ZendCon, I used this as an opportunity to visit several National Parks. I took away as much (if not more) from Arches, Zion, Sequoia, and Yosemite as I did from those four days in San Jose. Also, my brother and I almost died in a freak snowstorm in Iowa on the way there, but that is a different story.

Building a Hackintosh

Building a Hackintosh is something that is remarkably rewarding and fun (if you have a twisted sense of fun). It is also very educational. This marks my third Hackintosh, but my goal this time was to use most of my existing hardware and end up with a machine I might actually want to use on a daily basis. This article is a getting started guide from my perspective on building your own Hackintosh.

Beaus Dual Monitor Hackintosh

Should you choose to do so, you are embarking on an adventure in understanding how OSX works and will soon experience the excitement you get from learning something new and accomplishing a goal. You will likely need to consult others for help and second guess your decision to start this project more than once.

Couldn’t you just go out and buy a $599 Mac Mini? Yes. If you are asking that question then you have missed the point. This adventure involves a lot of pulling your hair out, cursing, and possibly a trip or two to Best Buy. Regarding money, you can certainly save some money by building your own Hackintosh, especially if you compare pricing on the high end of the Apple lineup. You can also build a pretty capable Hackintosh for a few hundred dollars. However, this is not about how much or little you spend, like I said, it’s an adventure.

I owe a lot to the great people and websites like tonymacx86.com and insanelymac.com that have been invaluable resources to me in getting everything on my Hackintosh working.  I could not have done it without the tools and knowledge contained there.

If you’re ready to go, lets get started. You just might get the satisfaction of a home-brew Hackintosh you can call your own. This process has some general information on getting started and then the specifics of my hardware and procedures to get everything working.

Hardware Considerations:
At the time of building my Hackintosh, OSX 10.7.4. Lion was the latest version of OSX.

Selecting which hardware to purchase is tough. I actually purchased most of my components nearly two years prior, but I had in mind that I was going to create a Hackintosh, so I tried to stick to some generally acceptable hardware.

A Gigabyte or Asus motherboard is a fairly safe choice. I chose an Asus board at the time, but would probably go Gigabyte today. Regarding Intel vs. AMD, you pretty much have to go Intel. By doing so, you can just purchase a copy of OSX to work with. There are some AMD solutions out there, but most are hacked up versions beyond what I would consider currently worth the effort.

Your hard drive should be 1TB or under for installation. Most people seem to have problems using IDE drives. I used a WD 1TB SATA drive. Furthermore, you will usually be told to set your BIOS to use AHCI mode instead of IDE mode. You may also have to change some power management settings, but that differs from board to board. In my configuration, I only had to set my hard drive controller to use AHCI.

Choosing the right video card for me was certainly the biggest challenge. While it seems that ATI is currently supported a little better, I always seem to get burned when I pick ATI. I also added some headaches by insisting on dual monitor support for my setup. That definitely complicates matters and resulted in a trip to the computer store. After vowing twice to never buy another ATI card, I decided to dump my partially working (with one monitor) XFX ATI Radeon HD 4670 and go with a cheap $40 eVGA Nvidia 8400 GS 512MB DDR3 card. Don’t ever assume that because someone says their Nvidia such and such model is working great that your card of the same model will work. The amount of RAM, manufacturer (eVGA vs. XFX. vs. Asus, etc….) makes a difference. Be prepared to re-install 20 times or so when you screw everything up and can’t boot in single user mode.

The newer Intel processors support Intel HD 3000 series graphics built in, which is what the Mac Mini is currently using. It seems like people have had success going that route, but I haven’t personally tried it. I have the Intel HD 2000 series on my Asus board, so I opted to go with a separate PCIE card and just disabled the integrated graphics on the motherboard from BIOS.

If I were building completely from scratch today, I would probably stick to one of the pre-built configurations that have already been worked out from tonymacx86.com.

Audio can be a sticky subject as well, but that has been worked on a lot and I only had to check a box in MultiBeast to get my driver installed. I had the same good luck when it came to my built in ethernet.

Overview of the process:

BIOS:
Once you have all of your components put together, its tempting to get started. However, make sure you take the time to look at tonymac, or one of the other sites and read up on your motherboard and BIOS. You should set your AHCI mode and power settings before getting started. You should also start with a clean hard drive, or be prepared to wipe it out.

Creating a USB installer:
Getting a copy of OSX is fairly easy if you already own a Mac. I used my purchased copy from the AppStore and just downloaded it again. You can then run UniBeast (get it from www.tonymacx86.com) and it will take that copy and make a bootable USB thumb drive for you. Once you have that, you just need to set your BIOS to boot from USB and off you go.

Installation:
Once you run the USB, you should be presented with a boot menu (Chameleon). If you do nothing, in a few seconds it will be booting up the installation screen. If you get stuck at this point, there is a good chance you need to start researching your hardware and look for some settings you can try typing into the bootloader to get the install screen to come up. At the bootloader, pressing the spacebar will give you a boot prompt where you can start typing. Using -v will hide the Apple logo and show you what is happening and is probably your first line of defense in determining what is failing. You can then start searching the forums for this stuff, ask for help, or start trying some common boot flags like PCIRootUID=1 or GraphicsEnabler=no.

If everything went well, or is going well enough that you are in the installer (don’t worry about a non-optimal resolution right now), then you need to prepare your hard drive. You can run the disk utility from the menu. The simple choice here is to use 1 partition formatted as HFS journaled (I called it Lion) and in options make sure GUID is selected. I usually create a couple of extra paritions (one about half the size of my drive for Windows and another very small one for Tools), but you don’t need to this if you are confident in your ability to get everything working and you don’t want Windows, etc. Because I plan on installing Windows later, I left some free space aside for it. My tools partition is just a small (couple of GBs) partition that is also formatted for HFS that I can keep a copy of useful apps / tools / kexts on so that if I have to reinstall, I can just erase the main partition (Lion) and install over it without losing my downloads.

If the installation went well, the installer will reboot at the end. At this point, you still need to boot from your USB install drive. When the computer boots to the USB drive, you should now have your new Lion partition showing up in the boot options. Choose that option to boot your new Lion installation. If everything loads, then you are ready to start installing any extra drivers / utilities needed to get your Hackintosh working 100%. If you are stuck at a black screen, get a kernel panic, etc.. then it’s time to start hitting the forums and searching for your specific problem. Again, press the spacebar and use -v to get an idea of where your system is failing.

Optimizing for your hardware
The easiest way to get all of your hardware working is to use MultiBeast (www.tonymacx86.com). MultiBeast already has a lot of preset configurations for specific motherboards. You can then often get your sound, network and graphics working by using MultiBeast if they aren’t working already. When you run MultiBeast for the first time, you should leave the defaults checked which will install the Chameleon bootloader onto your hard drive so you’ll no longer need the USB drive. It’s also a good idea to see if your motherboard has a DSDT configuration from tonymacx86.com. A DSDT file will adjust specific settings regarding ACPI and BIOS that will make your system work properly with OSX. You can find out more about DSDT here.  It may be a good idea to just get your bootloader and custom DSDT working (if you have one), reboot and then run MultiBeast again to install your drivers.

In my case, after running MultiBeast, I needed to get my nVidia 8400GS working with dual monitors, sound and ethernet. While ethernet did work initially for me, after running MultiBeast with my custom DSDT, my settings were such that I needed to install the ethernet driver. I was able to use the RealTek driver under Networking and for sound, the Voodoo HDA 0.2 worked great. I pulled my hair out for a while thinking audio would start / stop working for no reason. My volume slider would show up but I wouldn’t hear audio sometimes. Finally, I realized you can option-click (on Win keyboard = alt-click) the volume slider and choose the correct speaker output. Mine was defaulting back to LogMeIn since I installed that.

Graphics:
I am currently using a Nvidia 8400GS card because it was cheap and I had some confidence that I could get it working fully with dual monitors before choosing a better replacement / perhaps a new system. I also have an ATI 4670, but had trouble getting dual monitor support and finally decided to spend $40 and cut my losses. I will likely revisit this again, but currently I have a fully working dual-monitor setup and I’m not a gamer.

When it comes to getting your graphics card working, you really have several ways to go about it. Because I seem to have better luck with NVidia, I will focus mainly on those, but touch on ATI as well.

The Chameleon bootloader has a feature called GraphicsEnabler. Each video card has a vendor ID and a device ID. This combined ID makes up your unique video card. OSX has many drivers (kexts) already built in, but since Apple knows every piece of hardware that ships in their machines, they only have the vendor/device ids specified for that hardware. By simply turning on GraphicsEnabler in Chamelon (it is by default), your unique hardware id will be injected into Apples hardware driver for your series of card automatically. This is the first thing to try and may get you going without further configuration.

If you weren’t so lucky as to just be able to turn on GraphicsEnabler=yes, then you may need to start getting dirty. Before you do, however, try booting with -v to see what is wrong. If you end up with what seems like a successful boot, but your monitor(s) go into sleep mode, you may have a framebuffer issue. Just knowing which series of card you have is not always enough because cards come in so many different configurations. You might have a card with dual dvi outputs, a dvi and a vga, hdmi, all three, etc… These different configurations can be adjusted on ATI cards by trying different preset configurations with the AtiConfig=something boot flag. NVidia cards often need to use and EFI string. The best thing to do is head over to the forums at insanelymac or tonymacx86 and start searching for your specific vendor / device id.

My eVGA Nvidia 8400gs has a DVI / VGA and HDMI output. My card would only work properly with the VGA output. Specifically, I needed to use the VGA and the DVI with VGA adapter for dual monitors, otherwise I would get an immediate power down of the monitors. To get my card working, I was able to edit the NVDANV50Hal.kext and put my vendor/device id in the list. As an experiment, I also was able to achieve the same results by downloading a hex file containing my EFI string and putting that directly in the chameleon boot file in the /Extra folder.

As soon as I got my 8400gs working, both screens lit up at 1920×1200 (my native resolution). However, just because you are able to get the resolution you need, you may not have QE/CI support. This is the built in hardware acceleration support you want so that things run smoothly and apps can take advantage of your video cards hardware. In Lion, you can’t easily tell if this is on just by looking, so there is a simple ripple effects test that will let you know quickly if its working.

When troubleshooting graphics cards, keep in mind that you should only be doing one method at a time. This is very important. If you can’t get it working by turning GraphicsEnabler=yes on, then you need to turn it off and try putting your vendor/deviceid directly into the driver (edit the Info.plist file, usually in the IOPCI section). If that doesn’t work, put it back the way it was and try using an EFI string by downloading a HEX file for your card and putting that in the chameleon boot file. With ATI cards, try the different framebuffer options with the AtiConfig= boot parameter. On nVidia, you can also look into using the NVEnabler kext. Just don’t do them all at once and keep track of each change and roll it back or you will find yourself re-installing OSX more often than you might like.

Conclusion:
If you stick to it, you can have a very solid and reliable Hackintosh that you built yourself. If you are successful, help others out and add your hardware configuration to one of the compatibility lists. There is an amazing community of people out there working together to make projects like this possible. Thank you.

Useful Tools:
UniBeast - Creates a USB bootable installer of OSX Lion.

MultiBeast – Installs the Chameleon bootloader and contains useful drivers and configuration utilities to get your Hackintosh working.

Chameleon Wizard – Adds a system pref pane that allows you to configure the Chameleon boot loader, including boot options, inject EFI strings and more. 

Carbon Copy Cloner - Backup your system to an external drive or another partition that can be booted and restored very easily.

Kext Utility – Utility to install kexts into your system/library/extensions folder that sets the permissions, backs up the old kexts and deletes caches for you. 

TextWrangler – A free text editor useful for editing plist files.

My Hackintosh
Hardware: Asus Motherboard P7H55-M Pro
Processor: 3.21GHz Intel Core i3
Graphics: eVGA nVidia 8400GS 512MB DDR3
Ram: 8GB DDR3
HDD: WD SATA 1TB
Dual 24″ Displays at 1920×1200
OSX Lion 10.7.4
Dual Monitor Support at 1920×1200

Notes: Dual Monitors working when using VGA port for monitor 1 and monitor 2 with VGA adapter in DVI port.

1. Use UniBeast to install 10.7.4 from USB
2. Run MultiBeast 4.5.2 and install EasyBeast with the defaults.
3. Enable show all files: In terminal: “defaults write com.apple.finder AppleShowAllFiles TRUE” and then “killall Finder”.
4. Copy System/Library/Extensions/NVDANV50Hal.kext to Desktop, right click, show Package contents.
5. Edit the Info.plist (I use TextWrangler).
6. Add 0x10c310de&0xffe0ffff to the list of devices in IOPCIPrimaryMatch (Put it in the correct order, for me it was last in the list).
7. Install your modified Kext with Kext Utility.
8. Update /Extra/org.chameleon.Boot.plist with GraphicsEnabler=no and reboot.
9. Make sure you are using the VGA port or the DVI port and a VGA adapter, or both for dual display to work.

Audio:
Use MultiBeast and add Audio-Universal-VoodooHDA 0.2.1

Network:
Use MultiBeast and add Network-Lnx2Mac’s RealtekRTL81x Ethernet v0.0.90

Post Install Notes:
The App Store would not work for me until I modified /Extra/org.chameleon.Boot.plist with PCIRootUID=0.

UPDATE 6/26/2012

Graphics:
Since my original post, I decided to go ahead and replace my video card. For about $100, I purchased a Sapphire 11192-12-20G Radeon HD 6670 1GB Ddr3 PCI-Express Video Card, which I am happy to say works perfectly out of the box with GraphicsEnabler=false. This was a nice speed boost from the 8400GS I purchased as a getting started card. This card also looks promising with Mountain Lion.

SSD:
To round out the system, I made my WD drive a secondary drive and put a Mushkin SATA III Chronos drive in as a boot drive. I used CCC to move everything over and it’s working fantastic.