Archive for the php Category

Web applications can be traced or debugged on many layers. The highest layer would be what some frameworks like symfony provide in their development consoles. Another layer would be to look at output from php-xdebug in kcachegrind to do profiling. But the lowest possible level is to look at actual system calls used by a running application.

FreeBSD has a base system utility called ktrace. It allows administrator to attach to a running process and log all system calls used by the process. How to use it to trace a web application running under apache?

First apache has to be started in debug mode, with only one worked running. This will make finding the apache process running our application easier to find.

This is how to start apache in debug mode:

httpd -X &
[1] 34702

Running this in the background will return the ID of the process: 34702. Now, all we have to do is to attach ktrace to this process:

ktrace -dip 34702

option “-d” means that all descendants (current child processes) of the process will also be traced and option “-i” means that all process spawned by our process will also be traced. “-p” option is used to give the PID of the traced process.

at this point we can run our application from the browser and after doing so take a look at system calls used. Ktrace saves all system calls to a ‘ktrace.out” file in the current directory. kdump utility is used to display contents of this file:

kdump -R

“-R” option will display time taken between entries so we can estimate how long a syscall took to finish.

we can detach ktrace and stop tracing the process by:

ktrace -C

I couldn’t find on symfony’s website what options you can pass to the object_select_tag function. It’s definition looks like this:

function object_select_tag($object, $method, $options = array(), $default_value = null)

and options can be:

  • peer_method – peer method you want to use to fetch options. useful for sorting, limiting output etc.
  • text_method – method used to display labels for your options
  • include_custom – your customized option
  • include_title – creates a title for the whole selection based on the name of the called method
  • include_blank – adds blank (“”) option to your select tag

I’m not sure if it’s the best way of doing it, but this method of creating web services with wso2 works for me. A bonus here is that it doesn’t involve creating or modyfying any XML/WSDL files as all this is autogenerated or handled by the framework itself.

This example service will return N random digits from a given range.

wsdl autogeneration

wso2 has a nice feature of generating wsdl files based on service configuration. It can do even better than that – it can generate a wsdl file for your service based on the comments you use for functions that describe your service. Of course these comments have to be in a special format, but this format is nothing else than dotproject-style comments that can be used to automatically document your code. Here is an example, it doesn’t implement anything yet, it’s only used to generate a wsdl definition. To avoid URL changes in the service location specified in the generated wsdl I’m creating it in random/index.php in my web server’s root directory, which will be replaced by the service implementation later on:

<?php
/**
* @namespace http://server.com/random
*/

class RandomNumber
{
/**
* @var integer $number
*/

public $number;
}

/**
* @param integer $num number of random digits
* @param integer $min minimum random number
* @param integer $max maximum random number
* @return array of object RandomNumber $numbers array of random numbers generated
*/

function getRandom($num, $min, $max)
{
return new RandomNumber();
}

$service = new WSService(array("operations" => array("getRandom")));
$service->reply();
?>

When you access http://server.com/random/?wsdl you’ll get your wsdl file generated for the service documented above. Save it in your services directory as random.wsdl.

service and client autogeneration

Now we can use this file to generate both a service template and a sample client template.

In wso2-php package there is a file called wsdl2php.php. Use it to generate both templates:

> php wsdl2php.php -s random.wsdl > server.php
> php wsdl2php.php random.wsdl > client.php

you can keep a copy of your index.php file used to generate the wsdl file and replace it with the generated server.php

> cp index.php generate.php; mv server.php index.php

service implementation

At this point you can implement your service, edit your index.php file, read the comments there, and add this simple implementation to the getRandom function:

$response = new getRandomResponse();
for ($i = 1; $i >= $input->num; $i++) {
  $n = new RandomNumber();
  $n->number = rand($input->min, $input->max);
  $response->numbers[] = $n;
}
return $response;

implementation of a sample client

and now modify your client to test it, under //TODO fill in the class fields of $input to match your business logic add:

$input->num = 10;
$input->min = 1;
$input->max = 100;

and implement the business logic to consume your response:

foreach ($response->numbers as $n) {
  printf("%d", $n->number);
}

Start client.php in your browser – you should be able to see 10 randomly generated numbers ;)

Update (2008-06-04): This patch also works with the latest (1.3.1) version of wsf/php.

WSO is a web services framework I’ve been recently playing with. There are versions of it for C, php, ruby, perl, and some other languages… The php version comes as a php module that needs to be compiled from source (or installed as a package if you’re running a linux distribution that has it) and added to your php configuration.

The source code compiles under windows, linux and OS X but needs some patching to work under FreeBSD.

you’ll need libxml2, libiconv, zlib and sqlite (or mysql) libraries installed from ports.

Here is how to do it:

# fetch http://dist.wso2.org/products/wsf/php/1.2.1/wso2-wsf-php-src-1.2.1.tar.gz
# fetch http://bsd.dischaos.com/files/wso2-1.2.1-freebsd.patch
# tar xvfz wso2-wsf-php-src-1.2.1.tar.gz
# patch -p0 < wso2-1.2.1-freebsd.patch
# setenv CPATH /usr/local/include
# setenv LD_LIBRARY_PATH /usr/local/lib
# cd wso2-wsf-php-src-1.2.1
# ./configure LDFLAGS="-lcompat" && make && make install

now just add wo.so extension to your /usr/local/etc/php/extensions. You’ll probably also need xml and xsl php extensions to have everything in wo working. Also, I copied the scripts directory from the wso2 package to /usr/local/share/wso2 and added this directory to include_path.

vim key mappings for php/symfony

| February 6th, 2008

I’ve recently added these key mappings to my .vimrc file:

map <C-t> :!php -l %<CR>

this checks php syntax of the currently edited file after hitting CTRL-t.

map <F9> :!php ./%<CR>

press F9 to run your php script.

map <C-s> :!d=`pwd`; until [ -f symfony ] ; do if [ `pwd` = "/" ] ;\
then exit ; fi ; cd ../; done; symfony cc; cd $d<CR>

this may be useful when working with symfony projects. After making some changes in your symfony project you have to clear cache if you want to preview them in your browser. This maps CTRL-s with “symfony cc” command. You can run it from any subdirectory of your symfony project.