[Xapian-devel] PHP Latest

Olly Betts olly at survex.com
Thu Apr 20 06:01:45 BST 2006


On Wed, Apr 19, 2006 at 01:23:29PM +0200, Daniel M?nard wrote:
> Olly Betts a écrit :
> >Currently the arguments are just called $arg0, $arg1 (...)
> >I just wanted to avoid having to worry for now about names 
> >being invalid in PHP or clashing with something.
> 
> C++ and PHP syntax for naming identifiers are quite similar, and unlike 
> functions names which can clash (as you already know : empty, clone...), 
> I don't think there are "reserved" variables names in PHP, so it 
> probably won't clash with anything, and it would be a nice bonus to have 
> real parameter names.

This page seems to say there are some reserved variable names ($argc,
$argv, $PHP_SELF, $HTTP_*):

http://aspn.activestate.com/ASPN/docs/PHP/reserved.html

I've not actually tested if it causes a problem to use them as a
parameter name - if it does, we can easily invent a suitable renaming
scheme.

Anyway, ignoring that for now, I'm now wrapping optional parameters as
PHP optional parameters.  There's a wrinkle here that the C++ values
can be fairly arbitrary expressions, whereas we need expressions which
are valid in PHP.  I think the simplest thing to do is check for:

(a) integers
(b) floating point values
(c) strings
(d) true and false
(e) NULL

And allow those (adjusting syntax where necessary - e.g. the C++ literal
strng "$variable" would be interpolated in PHP I believe), with anything
more complicated being handled as if it were an overloaded method.

Anyway, this reduces the number of methods which use get_func_args and
call_user_func_array to 23.  Some of those should get wrapped, such as
quartz_open.  I'm guessing the SWIG %rename there is confusing my code
but haven't investigated yet.

> >It's also unclear what to do for overloaded methods if a parameter
> >name varies in each overloaded version.  Perhaps call it
> >"$foo_or_bar_or_baz" if it has names "foo", "bar", and "baz" in
> >different overloads?
>
> This is the approach I took in my wrapper e.g.: 
> deleteDocument($docID_or_term)

I'll look into this, but I've not implemented it yet.

> Remember that the code only tests 3 functions (new_document, 
> document_set_data and document_add_posting) :
> http://www.bdsp.tm.fr/aed/xapian/call_test.php.txt

It's worth noting that document_add_posting is the most performance
critical method for an indexer, since it's the method you're going
to call most by a large margin (unless you're not indexing with
positional information.)

> the new xapian_wrap.cc which now do some coercion is not significantly
> slower (9.32 vs 8.88), 

I'm not convinced that should add any overhead to the native calls
to the flat functions - the coercion check I added wasn't in the
code path this would take (I added it as an extra check just before
reporting a type error).  I wonder where this slowdown came from.

Assuming this slowdown repeatable, is vanilla 0.9.5 the same speed as
0.9.4 or the patched version?

> So it seems that this is the creation of a temporary array for handling 
> the parameters (either with get_func_args or with array) which takes 
> time. Too sad it makes such a difference...

Annoying, but we avoid it in many cases now.

> >Functions/methods with no optional parameters and the same number of
> >parameters in each overload now get parameter lists instead of using
> >func_get_args and call_user_func_array.  
> > 
> >
> >I don't think we know the default values in SWIG (...)

I was wrong - we do.  Though it will be C++ code, so not necessarily
valid PHP...

> I can imagine that it will be difficult to have parameter lists for 
> *all* functions because of overloading...
> But perhaps the "with no optional parameters" condition could be 
> removed, handling optional parameters as non-optional ones ?
> For example, we would get function add_posting($tname, $tpos, $wdfinc), 
> which would require to always pass the wdfinc argument.
> Or perhaps we could generate function add_posting($tname, $tpos, 
> $wdfinc=null)
> (i.e. null as default value for all optional parameters), with the c 
> wrapper doing some magic like "if arg is null, don't pass it to xapian".. ?

We'd need to avoid this where null is a valid value, and it also means
that we can't complain if we're passed null where we want some other
value which isn't totally ideal.

I wondered about some trick like this:

class SwigPlaceHolder {
    function __construct() {}
};

And then a complicated overloading situation might look like:

class Query {
    function __construct($arg1,$arg2=new SwigPlaceHolder(),$arg3=new SwigPlaceHolder()) {
	if ($arg2 instanceof SwigPlaceHolder)
	    return new_Query($arg1);
	if ($arg3 instanceof SwigPlaceHolder)
	    return new_Query($arg1,$arg2);
	return new_Query($arg1,$arg2,$arg3);
    }
};

But it seems that PHP only accepts a constant for a default parameter
value - I can't use new or a variable holding an instance of
SwigPlaceHolder.

> I will also try to think about having native php iterators...
> As Paul said in a previous mail, we will have to implement the iterator 
> (or perhaps the Iterator Aggregate) interfaces, but we can also have to 
> add new methods (for example : for each method like "xxx_begin", add a 
> new method "xxx" wich return the php iterator), so one can write
> foreach ($document->values() as $no=>$value) echo "$no : $value\n";
> 
> Would it be possible to generate this kind of arbitrary stuff with SWIG ?

To some extent at least it probably is, but I think you'd need at
least some hand-crafted code to capture the different features.  For the
Pythonic iterators we just have fully hand crafted Python code which we
get SWIG to insert into its generated file (see python/extra.i).  

Latest version:

http://www.oligarchy.co.uk/xapian/patches/swig-php-gen-oo-wrappers7.patch
http://www.oligarchy.co.uk/xapian/patches/xapian7.phps
http://www.oligarchy.co.uk/xapian/patches/xapian_wrap7.cc

Cheers,
    Olly



More information about the Xapian-devel mailing list