• PEAR XML_RPC Part 2 Apr 14, 2005

    Posted by Mike Naberezny in PHP

    Regarding my earlier woes about XML-RPC functions in the global scope, upgrading to the latest stable version of XML_RPC has mostly alleviated the problem. This complaint was addressed in Bug 3363 and fixed in version 1.2.0RC7. Since this fix, the dispatch map can now utilize class functions, albeit only statically. In the dispmap, the functions may be declared one of two ways:

    'function' => 'myClass::rpcFunction'
    

    or

    'function' => array('myClass', 'rpcFunction')
    

    Allowing class functions to be mapped is a great improvement. I am now using a class for my XML-RPC API, with a class method to return the dispmap to be passed into XML_RPC_Server.

    The ability for XML_RPC_Server to call class functions has an additional benefit for PHP5 users, at least until something like XML_RPC2 becomes stable. In PHP5, the function get_class_methods() is now case sensitive, so introspection may be used to build the function declarations in the dispmap. However, this will still not be enough to generate the method signature or docstring. PHP5’s Reflection API can accomplish this, and it can even be used to get the docstring.

  • Python Mystery Powers Apr 4, 2005

    Posted by Mike Naberezny in Python

    Beginning Python programmers can be easily confused by the numeric operator for exponents. In many languages, the statement:

    print(2^2)
    

    Will return 4, or 2 raised to the power of 2. However, the ^ operator in Python has a completely different meaning. It actually returns the bitwise exclusive OR of the two numbers. For the example of 2^2, the number 0 will be returned instead of the expected 4.

    To express exponents in Python, use either:

    x = pow(a,b)
    x = a**b
    
  • Python Module “time” Apr 4, 2005

    Posted by Mike Naberezny in Python

    Python’s time module provides some very useful functions for working with time and dates.

    One useful function is sleep(), which pauses the program for a given number of seconds. I use this when I need to wait a fixed time period for physical events, such as a thermal soaking.

    The function time() returns the local time in the ever-useful number of seconds since the UNIX epoch. An interesting quirk is that accuracy of smaller than a second is available on some operating systems and this function will actually return with a floating-point number. Use Python’s int() if this is not desirable.

    The functions gmtime() and localtime() return the time in a 9-tuple which is somewhat unusual, however it can be handy for quickly extracting parts of the time. For example, time.localtime()[0] will return the four-digit year.

  • PHP 4 Functions and PEAR XML_RPC Mar 27, 2005

    Posted by Mike Naberezny in PHP

    Lately, I’ve been working with the PEAR package XML_RPC on multiple projects. Overall, the package is well done but there are some limitations of PHP 4 that make using it frustrating in some ways.

    The XML_RPC_Server class allows you to create a dispatch map of XML-RPC method calls to PHP functions. The means by which it calls these functions is with PHP’s call_user_func(). However, only functions in the global scope can be called. If your XML-RPC API functions are contained in their own file, this isn’t quite as bad as it sounds.

    $yourObject = new YourObject();
    function rpc_ping() {
      global $yourObject;
      $yourObject->doSomething();
    }
    

    While it’s certainly not ideal, it’s reasonable. As long as the RPC server code is usually isolated in its own PHP file, it stays manageable.

    It’s a good idea to name all of your functions that are mapped to RPC methods with the same prefix, such as rpc_. This keeps them somewhat grouped, even if they can’t be in a class. Having them all named with the same prefix would lead one to believe that the dispatch map could then be built automatically by using PHP introspection. However, this is problematic due to PHP 4’s case insensitivity.

    The function get_defined_functions() will return the names of all of the functions in the global scope, however the function names will be returned in all lowercase. This is true of get_defined_functions() in both PHP 4 and PHP 5 as of 5.0.3. However, it should be noted that in PHP 5, the functions get_class(), get_parent_class(), and get_class_methods() will return method names in the proper case that they were declared. These three functions are case insensitive in PHP 4, and return all lowercase.

    XML-RPC method calls are case sensitive, so using get_defined_functions() is not suitable. I have seen at least two XML-RPC implementations for PHP where method calls are case insensitive due to this problem, which is incorrect. I also saw this technique proposed as an addition to the XML_RPC package in the PEAR bugtracker, however thankfully it was not accepted. XML-RPC servers written in PHP need to comply with the specification, regardless of the “features” of the language.

    I think that the best way to build the dispatch map is still by hand. This is tedious but it has the advantage of forcing you to think about each function being mapped, and it also gives you the opportunity to define a docstring and signature for each method in the map.