So you’re now in charge of some kind of event and people are going to need tickets to get in. You could do it the old fashion way and actually have people at the door checking the tickets, but that is so 1980’s and also so easy to forge (for the nefarious). Event organizers are adament that tickets are only used once and so they want to use some kind of barcode reader to ensure that tickets are valid and you are responsible for the web side of this.
An easy way to solve this conundrum is to use a combination of Zend_Pdf and the new Zend_Barcode in your application. Barcodes are actually surprisingly simple to do, but you still have to make them. Zend_Barcode makes it simple AND fun. OK. I don’t know about fun, but less bad.
The tickets will be on standard paper so people can easily print them out from their regular printer. We also want them to be look a little nice, so we’ll be adding some graphics. I love great design, but I suck at it, so nobody complain that the example doesn’t look good.
The first thing we need to do is to set up our script so we’ll just start with the basics.
require_once 'Zend/Loader/Autoloader.php'; Zend_Loader_Autoloader::getInstance()->setFallbackAutoloader(true); $ticketNum = mt_rand(0, PHP_INT_MAX);
Obviously, $ticketNum would actually be a generated value, probably not a simple random number since that could be duplicated. The value for $ticketNum also needs to be valid according to the individual adapter. Each adapter has one or more validators with the prefix Zend_Validate_Barcode. In this case a simple number was sufficient for the purposes of testing.
The next thing we need to do is to create the actual barcode image.
$barcodeOptions = array('text' => $ticketNum); $bc = Zend_Barcode::factory( 'code39', 'image', $barcodeOptions, array() ); /* @var $bc Zend_Barcode */ $res = $bc->draw(); $filename = tempnam('/tmp', 'image').'.png'; imagepng($res, $filename);
What we do here is use the factory to create an instance of Zend_Barcode which we then write to the file system. You don’t need to write it to the file system. You can keep it in memory. But from a teaching perspective this is a little easier since you can see it seperately from the PDF document.
Several people have notified me that you do not need to create a temp file (thanks for doing so, BTW). While I was aware of that, I probably didn’t say it very clearly in the paragraph preceeding this. The reason I didn’t go that route was so that you could see the actual output of the barcode image file. If you are going to be using something like this in a real-life application, absolutely use PDF renderer for the barcode instead. But here I wanted to show it in a way where you could see the image ahead of time.
The next thing we do is create a new PDF document that we’re going to work with and add the page that we’re going to place our content on.
$pdf = new Zend_Pdf(); $pdf->pages = $page = new Zend_Pdf_Page(Zend_Pdf_Page::SIZE_A4);
After that we will place a header in the PDF file. Here is the header image.
No, this is not an official Zendcon 2010 All Access Pass. But it could be…
Now that we have our header image let’s add it to the page.
$image = Zend_Pdf_Image::imageWithPath('allaccess.png'); $page->drawImage($image, 10, 680, 586, 820);
You might be asking yourself “what are all those funky numbers?” They are a box that defines the area that the image is going to inhabit. In this case the start position will be 10×680 (starting from the bottom left of the page) and go to 586×820. The image is 576 (586-1) x 140 (820-680).
Now having the image attached to the page we can add our barcode image
$image = Zend_Pdf_Image::imageWithPath($filename); $size = getimagesize($filename); $page->drawImage($image, 10, 500, $size+10, $size+500);
Same deal as before except that since we don’t know what the image size is going to be we called getimagesize(). The size can be defined, but for clarity I did not do it here. Your image will look something like this
After that all we need to do is render the PDF file, do something with it, and delete the temporary files.
$pdfFilename = tempnam('/tmp', 'pdf').'.pdf'; $pdf->save($pdfFilename); // Do something unlink($filename); unlink($pdfFilename);
And with that we have our PDF-based, scan-able ticket.
Adapters for Zend_Barcode
- Error (Used for handling errors)
- Create the Zend_Barcode image
- Create the Zend_Pdf document
- Create the Zend_Pdf page, attaching it to the document
- Delete temp files