[svn:PHP-Sandwich] rev 1015 - in PHP-Sandwich/trunk: . t

[email protected] 22 Apr 2005 21:20:12 -0000
Newsgroups perl.php.sandwich.dev
Message-ID <[email protected]>
Author: gschlossnagle
Date: Fri Apr 22 14:20:12 2005
New Revision: 1015

Added:
   PHP-Sandwich/trunk/t/10.t   (contents, props changed)
   PHP-Sandwich/trunk/t/9.t   (contents, props changed)
Modified:
   PHP-Sandwich/trunk/PHP.xs
   PHP-Sandwich/trunk/t/1.t
   PHP-Sandwich/trunk/t/3.t
   PHP-Sandwich/trunk/t/4.t
   PHP-Sandwich/trunk/t/5.t
   PHP-Sandwich/trunk/t/7.t
Log:
enhance class passing.

You can now instantiate PHP classes via

PHP::Interpreter::instantiate($classname, @params);



Modified: PHP-Sandwich/trunk/PHP.xs
==============================================================================
--- PHP-Sandwich/trunk/PHP.xs	(original)
+++ PHP-Sandwich/trunk/PHP.xs	Fri Apr 22 14:20:12 2005
@@ -421,6 +421,71 @@
       sandwich_interp_dec_ref(interp);
     }
 
+SV* SAND_instantiate(interp, class, ...)
+  PHP_Interpreter interp;
+  char *class;
+  CODE:
+    {
+      void *old_ctx;
+      char *croakstr = NULL;
+      zval *obj = NULL;
+      
+      old_ctx = tsrm_set_interpreter_context(interp->ctx);
+      {
+        zend_fcall_info fci;
+        zval method;
+        zval *retval;
+        zend_class_entry *ce;
+        int param_count = 0;
+        zval ***params = NULL;
+        zend_function *constructor;
+        int i;
+        TSRMLS_FETCH();
+        MAKE_STD_ZVAL(obj);
+        ce = zend_fetch_class(class, strlen(class), ZEND_FETCH_CLASS_DEFAULT TSRMLS_CC);
+        object_init_ex(obj, ce);
+        fci.size = sizeof(fci);
+        fci.function_table = EG(function_table);
+        fci.no_separation = 0;
+        fci.object_pp = &obj;
+        fci.retval_ptr_ptr = &retval;
+        fci.symbol_table = NULL;
+        if(items > 2) {
+          params = emalloc(sizeof(zval **) * (items - 2));
+          for(i = 2; i< items; i++) {
+            zval *arg = SvZval(ST(i));
+            params[i - 2] = &arg;
+          }
+          param_count = items - 2;
+        }
+        fci.param_count = param_count;
+        fci.params = params;
+
+        if(Z_OBJ_HT_P(obj)->get_constructor && (constructor = Z_OBJ_HT_P(obj)->get_constructor(obj TSRMLS_CC))) {
+          INIT_ZVAL(method);
+          ZVAL_STRING(&method, constructor->common.function_name, 1);
+          fci.function_name = &method;
+          if(zend_call_function(&fci, NULL TSRMLS_CC) == FAILURE) {
+            croakstr = "an error occured in object constructor";
+          }
+          zval_dtor(&method);
+        }
+        zval_dtor(retval);
+        if(fci.param_count > 0) {
+          int i;
+          for (i=0; i < fci.param_count; i++) {
+              zval_ptr_dtor(fci.params[i]);
+          }
+          efree(fci.params);
+        }
+      }
+      if(obj) RETVAL = newSVzval(obj, interp);
+      tsrm_set_interpreter_context(old_ctx);
+      if(croakstr) croak(croakstr);
+    }
+  OUTPUT:
+    RETVAL
+
 MODULE = PHP PACKAGE = PHP::Class PREFIX=PHP_V_C_
 
 REQUIRE:        1.9505
@@ -775,3 +840,51 @@
       free(pclass);
     }
 
+SV* PHP_V_C_create(in, class, ...)
+  SV *in;
+  char *class;
+  CODE:
+    {
+      PHP_Class pclass;
+      void *old_ctx;
+      char *croakstr = NULL;
+      MAGIC *mg;
+      zval *obj;
+      
+      mg = mg_find((SvRV(in)), PERL_MAGIC_ext);
+      if(!mg) return;
+      pclass = (PHP_Class) SvIV(SvRV(mg->mg_obj));
+      if(!pclass) return;
+      old_ctx = tsrm_set_interpreter_context(pclass->interp->ctx);
+      {
+        zend_fcall_info fci;
+        zval method;
+        zend_class_entry *ce;
+        int param_count = 0;
+        zval ***params = NULL;
+        TSRMLS_FETCH();
+        MAKE_STD_ZVAL(obj);
+        ce = zend_fetch_class(class, strlen(class), ZEND_FETCH_CLASS_DEFAULT TSRMLS_CC);
+        object_init_ex(obj, ce);
+        INIT_ZVAL(method);
+        ZVAL_STRING(&method, class, 1);
+        fci.param_count = param_count;
+        fci.params = params;
+        fci.size = sizeof(fci);
+        fci.function_table = EG(function_table);
+        fci.function_name = &method;
+        fci.no_separation = 0;
+        fci.object_pp = &obj;
+        fci.retval_ptr_ptr = NULL;
+        if(zend_call_function(&fci, NULL TSRMLS_CC) == FAILURE) {
+          croakstr = "an error occured in object constructor";
+        }
+        else {
+          RETVAL = newSVzval(obj, pclass->interp);
+        }
+      }
+      tsrm_set_interpreter_context(old_ctx);
+      if(croakstr) croak(croakstr);
+    }
+  OUTPUT:
+    RETVAL

Modified: PHP-Sandwich/trunk/t/1.t
==============================================================================
--- PHP-Sandwich/trunk/t/1.t	(original)
+++ PHP-Sandwich/trunk/t/1.t	Fri Apr 22 14:20:12 2005
@@ -8,5 +8,5 @@
 }
 
 ok my $p = new PHP::Interpreter(), "Create new PHP interpreter";
-ok my $a1 = $p->include('test.inc')->call('ident', 1), "Including a PHP file and executing a function off it";
+ok my $a1 = $p->include('/home/george/PHP-Sandwich/trunk/t/test.inc')->call('ident', 1), "Including a PHP file and executing a function off it";
 is $a1, 1, 'We should get the proper value from the ident() function';

Added: PHP-Sandwich/trunk/t/10.t
==============================================================================
--- (empty file)
+++ PHP-Sandwich/trunk/t/10.t	Fri Apr 22 14:20:12 2005
@@ -0,0 +1,18 @@
+#!/opt/ecelerity/3rdParty/bin/perl 
+use strict;
+use Test::More tests => 6;
+use Data::Dumper;
+
+BEGIN {
+    diag 'Instantiate an internal class with PHP::Interpreter::instantiate()';
+    use_ok 'PHP' or die;
+    use_ok 'PHP::Interpreter' or die;
+    use_ok 'PHP::Class' or die;
+}
+
+ok my $p = new PHP::Interpreter(), "Create new PHP interpreter";
+
+my $arg = $p->instantiate('stdClass');
+
+is ref($arg), "PHP::Class::stdClass", "class membership correct";
+is $PHP::Class::stdClass::ISA[0], 'PHP::Class', 'class inherits correctly';

Modified: PHP-Sandwich/trunk/t/3.t
==============================================================================
--- PHP-Sandwich/trunk/t/3.t	(original)
+++ PHP-Sandwich/trunk/t/3.t	Fri Apr 22 14:20:12 2005
@@ -11,7 +11,7 @@
 diag "Testing passing Perl AVs to PHP functions.";
 
 ok my $p = PHP::Interpreter->new, "Create new PHP interpreter";
-ok $p->include('test.inc'), 
+ok $p->include('/home/george/PHP-Sandwich/trunk/t/test.inc');
   'include PHP testing suite';
 my @list = ('I', 'AM', 'AN', 'ARRAY');
 ok my $newlist = $p->ident(\@list), 'Pass an AV into PHP, return an AV.';

Modified: PHP-Sandwich/trunk/t/4.t
==============================================================================
--- PHP-Sandwich/trunk/t/4.t	(original)
+++ PHP-Sandwich/trunk/t/4.t	Fri Apr 22 14:20:12 2005
@@ -11,7 +11,7 @@
 diag "Test pashing hashes from Perl->PHP->Perl";
 
 ok my $p = new PHP::Interpreter(), "Create new PHP interpreter";
-ok $p->include('test.inc'), "include() PHP testing functions.";
+ok $p->include('/home/george/PHP-Sandwich/trunk/t/test.inc'), "include() PHP testing functions.";
 my $hash = { 'a' => 'alpha', 'b' => 'beta', 'c' => 'charlie' };
 ok my $arg = $p->ident($hash), "Pass a hash into PHP, recieve a hash back";
 

Modified: PHP-Sandwich/trunk/t/5.t
==============================================================================
--- PHP-Sandwich/trunk/t/5.t	(original)
+++ PHP-Sandwich/trunk/t/5.t	Fri Apr 22 14:20:12 2005
@@ -10,7 +10,7 @@
 }
 
 ok my $p = new PHP::Interpreter(), "Creating a new PHP::Interpreter.";
-ok $p->include('test.inc'), "including PHP testing functions.";
+ok $p->include('/home/george/PHP-Sandwich/trunk/t/test.inc'), "including PHP testing functions.";
 my @list = ('I', 'AM', 'AN', ['NESTED', 'ARRAY']);
 ok my $arg = $p->ident(\@list), "Pass in a nested array and return it.";
 is_deeply $arg, \@list, "Testing that return array equals passed array.";

Modified: PHP-Sandwich/trunk/t/7.t
==============================================================================
--- PHP-Sandwich/trunk/t/7.t	(original)
+++ PHP-Sandwich/trunk/t/7.t	Fri Apr 22 14:20:12 2005
@@ -7,16 +7,16 @@
     use_ok 'PHP' or die;
     use_ok 'PHP::Interpreter' or die;
 }
-
+my $inc = '/home/george/PHP-Sandwich/trunk/t/test.inc';
 ok my $p = new PHP::Interpreter(), "Create new PHP interpreter";
-ok my $a1 = $p->include('test.inc')->call('ident', 1), 
+ok my $a1 = $p->include($inc)->call('ident', 1), 
   "Including a PHP file and executing a function off iti via call";
 
 ok my $p2 = new PHP::Interpreter(), "Create new PHP interpreter";
-ok my $a1 = $p2->include('test.inc')->ident(1), 
+ok my $a1 = $p2->include($inc)->ident(1), 
   "Including a PHP file and executing a function off iti via AUTOLOAD";
 
 ok my $p3 = new PHP::Interpreter(), "Create new PHP interpreter";
-ok $p3->include('test.inc'), "Including a file";
+ok $p3->include($inc), "Including a file";
 ok $p3->ident(1), 
   "... and executing a function off it via AUTOLOAD (2)";

Added: PHP-Sandwich/trunk/t/9.t
==============================================================================
--- (empty file)
+++ PHP-Sandwich/trunk/t/9.t	Fri Apr 22 14:20:12 2005
@@ -0,0 +1,29 @@
+#!/opt/ecelerity/3rdParty/bin/perl 
+use strict;
+use Test::More tests => 9;
+use Data::Dumper;
+
+BEGIN {
+    diag 'Instantiate a userland class with PHP::Interpreter::instantiate()';
+    use_ok 'PHP' or die;
+    use_ok 'PHP::Interpreter' or die;
+    use_ok 'PHP::Class' or die;
+}
+
+ok my $p = new PHP::Interpreter(), "Create new PHP interpreter";
+$p->eval(q/
+class Foo { 
+  var $a = 789; 
+  function __construct($a) { $this->a = $a; }
+  function bar() { return 'george'; }
+}; 
+/);
+
+my $arg = $p->instantiate('Foo', 123);
+
+is ref($arg), "PHP::Class::Foo", "class membership correct";
+is $arg->{a}, 123, "attribute access";
+$arg->{a} = 456;
+is $arg->{a}, 456, "attribute writing";
+is $arg->bar(), 'george', 'function calls';
+is $PHP::Class::Foo::ISA[0], 'PHP::Class', 'class inherits correctly';