Archive

Posts Tagged ‘php’

The SimpleXML

March 27th, 2012 Comments off

The SimpleXML extensions is intended to provide a “very simple and easily usable toolset”. This description lets you think that is simple to use but a more accurate description is that it lets you use it for for quick and simple cases. The basic example looks good:

$movies = new SimpleXMLElement($xmlstr);
 
/* For each <character> node, we echo a separate <name>. */
foreach ($movies->movie->characters->character as $character) {
   echo $character->name, ' played by ', $character->actor, PHP_EOL;
}

One little issue: $character->name is an object not a regular php string. As a result, you have to cast everywhere as if you use a static language:

if((string) $foo->bar == 'etc') {

or

str_etc((string)$xml->str);

There are also small differences on what functions are available or how they work, depending on what version of PHP you use.

In case of a slightly more complex xml (like some custom data feed) it is an usual approach to convert the xml object to nested array structure. http://php.net/manual/en/book.simplexml.php has a section of user contributed notes that is full of post regarding this action. There are two basic approaches:

$array = json_decode(json_encode($xml), TRUE);
...
// some cleanup if neeed

and some recursive parsing of the xml tree. Both methods kind of work if applied for the right problem. This shows that for the more than basic tasks SimpleXML becomes cumbersome, a nuisance to use.

The extension could be improved a bit to make it more usable but I think a lot of problems come from the nature of the XML format. Most data feed providers do not actually need or use the power/complexity of the XML format and could use a lighter more suitable format. Used data from providers that could easily use csv or json. It is easier to generate, parse, debug and use a lot less bandwidth & processing power all at the cost of sounding less “enterprise”.

Categories: Programming Tags: , ,

PHP foreach and references

September 26th, 2011 Comments off

The foreach construct is an usual way to iterate over an array. Since PHP 5, you can also modify the array values using references. Here is one interesting side effect:

<?php
$a = range(1,5);
foreach($a as &$x) {
	$x++;
}
 
foreach($a as $x) {
	echo $x;
}

The output is 23455. This happens because the $x reference remains even after the foreach loop ends. The reference is destroyed if you unset $x after the loop.

This is not very well known. If you have the misfortune to maintain some scripts with a coding style involving little structure, lots of spaghetti code and nested includes than you might be very puzzled by the behavior of a regular foreach loop just because the iterating value was used previously as a reference.

Categories: Programming Tags: ,

How to Create a Pdf in Php Using Tcpdf

December 15th, 2009 Comments off

There are several ways to generate PDF files in PHP. Each has its strengths and weaknesses. TCPDF strikes a good balance although it is far from ideal.

The best way to transform some web page to php is to let the user print it. With some free software like PDFCreator, you can get far better results than anything you can achieve using the available php libraries. Sometimes a client really wants this option or you need to generate some kind of report on the fly. This is when TCPDF is a good choice.

There is no special handling to use the library. You can download it, unpack it and include it in your project. For some advanced features, you might need to allow writing in the cache and images folders. To use it, you include the tcpdf.php file and some configuration file. You will need to make a custom configuration for more advanced features but the default one will work in most cases.

require_once('tcpdf/config/lang/eng.php');
require_once('tcpdf/tcpdf.php');

If you use the library from a cronjob or command line you might get this error: PHP Notice:  Undefined variable: k_path_url in tcpdf\config\tcpdf_config.php on line 75

This is where a custom configuration file is useful but the fastest way to fix it is to just initialize that variable ahead of the config file. It will work for most of the tasks.

$k_path_url='';
require_once('tcpdf/config/lang/eng.php');
require_once('tcpdf/tcpdf.php');

The functionality is available using the TCPDF class. I think the OOP approach stops here because there are no other classes used (with a minor exception) and I assume the author took this path to compensate for the lack of name spaces in PHP.

The flow is simple: create a TCPDF class, call its methods to generate pages, text and drawings and then save the content. Here is an example:

<!--?php
require_once('tcpdf/config/lang/eng.php');
require_once('tcpdf/tcpdf.php');
 
// create new PDF document
$pdf = new TCPDF(); 
 
// set font
$pdf--->SetFont('times', '', 16);
 
// add a page
$pdf-&gt;AddPage();
 
// print a line
$pdf-&gt;Cell(0, 0, 'Some text');
 
// print html formated text
$pdf-&gt;writeHtml('Html text:
<b>Bold</b>');
 
// draw a circle
$pdf-&gt;Circle(30, 30, 10);
 
//Close and output PDF document
$pdf-&gt;Output('out.pdf', 'F');

The library includes a set of examples to demonstrate what it can do.

A TCPDF object maintains internal coordinates used to write text and html with Cell and writeHtml. These methods (and some other related) use these coordinates to maintain the flow of text on the page and add new pages if needed.  They also take into consideration the page margins and headers. The drawing functions are relative to the origin of the page and do not use the Cell coordinates system. This will complicate the job for reports requiring a good layout and a lot of drawing.

The html support is limited. The html needs to be well formatted and only a limited set of tags is supported. There is no error handling for unsupported html so in the best case you will only get some strange php warnings like division by zero and others. You will have to specify the width of the table cells to maintain a minimal control of the layout because the tables are not rendered/positioned as in an usual browser.  I advise against using tables to control the layout of the pdf pages. I assume you read something similar as a web developer.

As a conclusion, I avoid generating complex PDF files in php. TCPDF is the best for the task but it has limited functionality, a poor API and little documentation.

Categories: Programming Tags: , ,