Archive for the ‘PHP’ Category
The quest for client-side search query language
…just led me to CQL (Contextual Query Language). Thanks StackOverflow and njk for showing the way!
(Please note that since version 1.2, “Contextual Query Language” is changed from former “Common Query Language”)
This lets the user write advanced searches using logical operators, indexes, even proximities… So, let’s create a search for all the cql-to-php-to-sql libraries laying around waiting for to be implemented…
Kohana 2.x code completion in Eclipse PDT
Things are about to change with Kohana 3 just released…
Meanwhile, the Eclipse PDT editor can’t really cope with Kohanas class namings and folder structure. But of course there is a solution: Peter Bowyer’s zend_autocomplete (works in all Eclipse PDT implementations including my boosted FlexBuilder 3, not just Zend Studio!). Put it in your controller directory, run it – and it creates a file in the cache containing all Kohana system classes as well as your own application classes! This is what Eclipse needs to give you well-working code completion!

Thank you, Peter!
Kohana, Formo and many-to-many relations (“habtm”)
Just got the solution for how to handle many-to-many relations in Formo. Thank you, Ben!
Three tables, groups (id, name), users (id, name) and the pivot table groups_users(group_id, user_id).
class User_Model extends ORM {
protected $has_and_belongs_to_many = array('groups');
}
class Group_Model extends ORM {
protected $has_and_belongs_to_many = array('users');
}
And here’s how to in the controller handle display of an user form, complete with checkbuttons for toggling connections to groups:
public function user($id = false) {
$user = new User_Model($id);
$form = Formo::factory()
->orm($user)
->habtm('user', 'group')
->add('Submit');
if ($form->validate()) $form->save();
echo $form;
}
This gives the following form. The magic lies in the habtm plugin (has to be active either by Formo config or by Formo::factory()->plugin(‘habtm’). Not one single sql line, not one line of deadly tedious form populating and deriving…

Ok, not pretty, but that’s another story.
Soo proud. Just struck me what “habtm” stands for.
Na na, won’t tell ya!
Kohana PHP with ORM and Formo – db made easy!
After some days prototyping with Kohana, I start to realize the strength and beauty!
One of the every-day needs in my world is to coordinate different database tables to get things to work. Most of the time this is done by hand, using PhpMyAdmin. For basic stuff, this works fine, but very often there’s the bad feeling of should-have-a-real-admin-interface-for-this…
No bad feelings no more!
The combination of Kohana’s Object Relational Mapping library (ORM) and the Formo module makes it super-easy to create a table-admin-interface, including related tables. No SQL at all, no defining form layouts at all! (Ok, there can be a need for some validation information, some styling etc.)
Here’s an example, based on two tables, schools and students:
schools: <- Note: Table name in plural id:int autoincrement name:varchar students: <- Note: Table name in plural id:int autoincrement school_id:int <- Note! Referred table as singular + "_id" name:varchar
Two models for those tables:
// models/student.php
class Student_Model extends ORM {
protected $belongs_to = array("school");
// Defines the connection to school - "each student belonst to a school"
}
// models/school.php
class School_Model extends ORM {
protected $has_many = array("students");
// Defines the connection to students - "each school has many students"
}
So for the controller. Here’s the real beauty: In the listAll action below the schools are fetched, and ORM handles automatically the relationship and fetches all connected students as well!
// controllers/controllername.php
public function listAll() {
$schoolModel = new School_Model();
$schools = $schoolModel->find_all();
foreach ($schools as $school) {
echo "<br/><b>$school->name - ".html::anchor("controllername/school/{$school->id}", "edit")."</b>";
foreach ($school->students as $student) {
echo "<br/>- $student->name - ".html::anchor("controllername/student/{$student->id}", "edit");
}
}
}
The actions below handle both creation and editing of posts. The super-handy Formo library maps out a complete form – including dropselect for selecting a school for the students!
Kind of magic!
// controllers/ormtest.php
public function school($id = false) {
$school = new School_Model($id);
$form = Formo::factory()->orm($school)->add("Submit");
echo $form;
if ($form->validate()) {
$form->save();
}
}
public function student($id = false) {
$student = new Student_Model($id);
$form = Formo::factory()
->orm($student)
->add("Submit");
if ($form->validate()) $form->save();
echo $form;
}
The only “tricky” part is that you have to get the table names and references to them right according to the ORM naming conventions. Here’s a short summary:
- Table names should be plural
(“schools”, “students” – this makes sense because the table is a list with many items) - Referring field names should be singular plus “_id”
(“school_id” – logically because a single student belongs to one single school) - Model names should be singular.
(The model file for a student is named “student.php”, and the class is named “class Student_Model extends ORM”. A model most of the time represent one single item: one student or one school. The exception is when we want a listing of all items in the table. Have a look at the listAll code above.)
The models need to include information about the relations.
- The student belongs to one of many schools, therefore we use
protected $belongs_to = array(’schools’);
with plural in “schools” - The school has one or many students, thus
protected $has_many = array(’students’);
Note that this relates to a one-to-many relationship.
Happy crudding with Kohana
Another superb Kohana solution: CRUD Scaffold (projects.nathanbentley.com/projects/show/crudscaffold) by Nathan Bentley. Just install, write some controller and model lines, and you have a nice JQuery-driven table editor – just the way it should be!:

Thank you, Nathan!
Now, there’s just left to sort out how to handle related tables…
Archive solutions in Flex/Air environment – FlashArchiver (FAR) and WINE
Using zips in a combined Flex/Air environment isn’t that trivial.
When running through FlashPlayer in browser, a compressed zip needs a Adler32 checksum to be valid. This isn’t a standard feature in any of the php zip libraries that I’ve seen.
Edwin van Rijkom’s FAR archive (http://code.google.com/p/vanrijkom-flashlibs/) is a very slick solution to get around this. It uses a custom file format based on zip compression. In the server end, it’s command line archiving tools (win, osx and “linux”, read on…) does a neat job in compressing, and in the Flex/Air client delivers the decompressed files continously while streaming the archive – quickly enough to handle large files. The native not-quite-zip format might also initially confuse a nosy mind…
One major problem: The linux version doesn’t work well in apache-php-server environment because of dependencies of X server, wich causes “Gtk-WARNING : cannot open display” error. It might be possible to solve by creating an environment where X server is running, but that seems very unnessecary and odd for a command line tool. At least to me – wich basicaly means that it’s beyond my limited linux knowledge…
One working solution: Running the windows version of the far compressing tool through Wine. Not that elegant, maybe, and maybe not that secure either, but at least it works! This is how I’ve managed to get it to work:
- Installing Wine on my Debian server
- Putting the windows archiver tool far.exe in an application directory, /var/tools/far/bin/far.exe
- Creating an output directory for the resulting archive files, /var/tools/far/output/, also setting it’s chown to www-data to be able to be reached by Apache.
- Creating a /var/www/.wine/ directory, setting its chown to www-data – also to be able to be reached by Apache2. (Maybe there’s another solution that putting it in /var/www/ – haven’t figured out yet.)
- Calling it from my php script like this, creating a new far archive (newarchive.far) from the files in the directory filesdirectory/:
<?php $command = 'wine /var/tools/far/bin/far.exe /var/tools/far/output/newarchive.far filesdirectory/'; $return = exec($command, $output, $result); ?>
Thanks Lasse for help regarding the Gtk problems, and MathieuK and Mike on StackOverflow for sorting out the Wine stuff! And Edwin of course!
Php: Serializing xml to object
Not finding a xml-to-object solution that “normalizes” the result as far as possible down to object level , I decided to create one myself.
- Single item nodes and attributes are added as objects
- Multi item nodes are added as array of objects
I’m sure that this has already been done a thousand times before, in easier and more elegant ways, but what the heck! – spending life programming is fun!
The following wierd test-xml (intentionally badly structured!)…
<root> <car brand="Volvo" > <equipments> <equipment type="motor" style="strong" /> <equipment type="wheels" style="fast" /> </equipments> </car> <car brand="Saab" /> <car brand="Porsche" /> <dog name="Pluto" /> <books> <book title="Da Vinci code"> <author name="Dan Brown" pages="400"/> </book> <book title="The Holy Bible" pages="999"> <author name="Matthew" /> <author name="Mark" /> <author name="Luke" /> <author name="John" /> </book> </books> <car brand="Mercedes" /> <person name="John" age="23" /> <orphan /> <dog name="Lassie" /> <person name="Pete" age="32" weight="75" /> </root>
…gives the following result object:
stdClass Object (
[car] => Array (
[0] => stdClass Object (
[brand] => Volvo
[equipments] => stdClass Object (
[equipment] => Array (
[0] => stdClass Object (
[type] => motor
[style] => strong
)
[1] => stdClass Object (
[type] => wheels
[style] => fast
)
)
)
)
[1] => stdClass Object (
[brand] => Saab
)
[2] => stdClass Object (
[brand] => Porsche
)
[3] => stdClass Object (
[brand] => Mercedes
)
)
[dog] => Array (
[0] => stdClass Object (
[name] => Pluto
)
[1] => stdClass Object (
[name] => Lassie
)
)
[books] => stdClass Object (
[book] => Array (
[0] => stdClass Object (
[title] => Da Vinci code
[author] => stdClass Object (
[name] => Dan Brown
[pages] => 400
)
)
[1] => stdClass Object (
[title] => The Holy Bible
[pages] => 999
[author] => Array (
[0] => stdClass Object (
[name] => Matthew
)
[1] => stdClass Object (
[name] => Mark
)
[2] => stdClass Object (
[name] => Luke
)
[3] => stdClass Object (
[name] => John
)
)
)
)
)
[person] => Array (
[0] => stdClass Object (
[name] => John
[age] => 23
)
[1] => stdClass Object (
[name] => Pete
[age] => 32
[weight] => 75
)
)
[orphan] => stdClass Object (
)
)
And here’s the source code, implemented as a static function in XmlUtils class:
Class XmlUtils {
public static function xmlToObject($xml, $obj = null) {
if (!$obj) $obj = new StdClass();
//**********************************************************
// Create array of unique node names
$uniqueNodeNames = array();
foreach ($xml->children() as $xmlChild) {
@$uniqueNodeNames[$xmlChild->getName()]++;
}
//**********************************************************
// Create child types - object for single nodes, array of objects for multi nodes:
foreach ($uniqueNodeNames as $nodeName => $nodeCount) {
if ($nodeCount > 1) {
$obj->$nodeName = array();
for ($i=0; $i<$nodeCount; $i++) {
array_push($obj->$nodeName, new StdClass());
}
} else {
$obj->$nodeName = new StdClass();
}
}
//**********************************************************
// For each child node: add attributes as object properties and invoke recursion
$arrayIdx = array();
foreach ($xml->children() as $xmlChild) {
$str = trim($xmlChild);
//print_r($xmlChild->attributes());
$nodeText = trim($xmlChild);
$nodeName = $xmlChild->getName();
// If child is array
if (is_array($obj->$nodeName)) {
$idx = (int)@$arrayIdx[$nodeName];
$objArray = $obj->$nodeName;
// Add attributes as object properties
foreach($xmlChild->attributes() as $attributeType => $attributeValue) {
$objArray[$idx]->$attributeType = (string)$attributeValue;
}
// If element text (e.g. <node>ElementText<node>
if (strlen($nodeText)) $objArray[$idx]->$nodeName = $nodeText;
// Invoke recursion
XmlUtils::xmlToObject($xmlChild, $objArray[$idx]);
}
// If child is object
if (is_object($obj->$nodeName)) {
// Add attributes as object properties
foreach($xmlChild->attributes() as $attributeType => $attributeValue) {
$obj->$nodeName->$attributeType = (string)$attributeValue;
}
// If element text (e.g. <node>ElementText<node>
if (strlen($nodeText)) $obj->$nodeName->$nodeName = $nodeText;
// Invoke recursion
XmlUtils::xmlToObject($xmlChild, $obj->$nodeName);
}
@$arrayIdx[$nodeName]++;
}
return $obj;
}
public static function xmlFileToObject($xmlFileName) {
if (!file_exists($xmlFileName)) die ("XmlUtils::xmlFileToObject Error: $xmlFileName nonexistent!");
$xml = simplexml_load_file($xmlFileName);
return XmlUtils::xmlToObject($xml);
}
}
//**********************************
// Example usage:
$xmlFile = 'test.xml';
$resultObj = XmlUtils::xmlFileToObject($xmlFile);
Text element nodes (I hardly ever use them!) are added as an object property with the same name as the node object itself:
<root> <book author="Old McDonald">Once upon a time...</book> </root>'
thus gives the following object:
stdClass Object (
[book] => stdClass Object (
[author] => Old McDonald
[book] => Once upon a time...
)
)
Of course they could be added as strings (or array of strings), but as soon as the node has an attribute, it has to be treated as an object anyway…
Cheers!
Eclipse plugin of tomorrow? nWire for php
Just tried a beta of the comin nWire plugin for php in Eclipse PDT/Zend Studio. It brings super-handy code exploration, including graphical tree view of includes and method dependencies, to php environment.

Right now it works in Eclipse 3.5, not in my 3.3 environment, so I have to make some change in my FlexBuilder based Eclipse-setup before it can be a tool for me…
Not free, but 59 bucks for a personal license is nothing to grumble about.
Php: Creating an uncompressed zip archive
Such a trivial task! Just use one of the included php libraries..? No. After some hours googling, good old PEAR got me closer. The late Pear Archive_Zip has a ‘no_compression’ parameter option. So, does it work? No. Corrupt content.After some further investigation, I found a reported bug adressing this matter. And a solution!
Archives become corrupted when use packing with ‘no_comopresson’ option set to ‘true’. I solved the promlem by changing
$p_header['compression'] = 8; to $p_header['compression'] = ($p_params['no_compression'] ? 0 : 8);
in ‘zip.php’ file on line 1429.
Thank you, Kotusev!
Zend_Soap_Server returning object – working!
Here’s a source code example on how to return an object from a Zend_Soap_Server. Thanks to James Gordon’s blog!
<?php
// Simple Zend_Soap_Server example returning an object
//****************************************************
// Zend Framework 1.8
include_once 'Zend/Loader/Autoloader.php';
$loader = Zend_Loader_Autoloader::getInstance();
$loader->setFallbackAutoloader(true);
$loader->suppressNotFoundWarnings(false);
//****************************************************
require_once "Zend/Soap/Server.php";
require_once "Zend/Soap/AutoDiscover.php";
if(isset($_GET['wsdl'])) {
$autodiscover = new Zend_Soap_AutoDiscover('Zend_Soap_Wsdl_Strategy_ArrayOfTypeComplex');
$autodiscover->setClass('TestService');
$autodiscover->handle();
} else {
$soap = new Zend_Soap_Server("http://localhost/ZendSoap/services/test.php?wsdl"); // this current file here
$soap->setClass('TestService');
$soap->handle();
}
//*************************************
// Classes used by getGroup service method below
class Person
{
/** @var string */
public $name = '';
}
class Group
{
/** @var Person[] */
public $persons;
}
//*************************************
class TestService
{
/**
* @return Group
*/
public function getGroup()
{
$group = new Group();
$person = new Person();
$person->name = "Annah";
$group->persons[] = $person;
$person = new Person();
$person->name = "Sarah";
$group->persons[] = $person;
return $group;
}
}
Leave a Comment
Leave a Comment
Leave a Comment