/[cvs]/nfo/php/libs/org.netfrag.glib/php_extensions.php
ViewVC logotype

Annotation of /nfo/php/libs/org.netfrag.glib/php_extensions.php

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.4 - (hide annotations)
Wed Mar 5 23:16:46 2003 UTC (21 years, 5 months ago) by joko
Branch: MAIN
Changes since 1.3: +5 -2 lines
updated docu - phpDocumentor is very strict about its 'blocks'...

1 joko 1.1 <?php
2    
3     /**
4     * This file contains some core functions extending php.
5     *
6     * @author Andreas Motl <andreas.motl@ilo.de>
7     * @package org.netfrag.glib
8 joko 1.3 * @name php
9 joko 1.1 *
10     */
11    
12     /**
13 joko 1.4 * $Id: php_extensions.php,v 1.3 2003/03/05 18:54:41 joko Exp $
14 joko 1.2 *
15     * $Log: php_extensions.php,v $
16 joko 1.4 * Revision 1.3 2003/03/05 18:54:41 joko
17     * updated docu - phpDocumentor is very strict about its 'blocks'...
18     *
19 joko 1.3 * Revision 1.2 2003/03/05 11:58:49 joko
20     * modified is_hash, mkInstance and others
21     *
22 joko 1.2 * Revision 1.1 2003/03/03 21:08:21 joko
23     * refactored from flib/utils
24 joko 1.1 *
25     *
26     */
27    
28    
29     /**
30     * --- shortcut functions
31     * Is there a mechanism in php to 'export' these methods
32     * to the global symbol table automagically?
33     * We wouldn't require declaring these shortcuts below and
34     * could also do some nice stuff at runtime.
35     * (maybe resembling CPAN's Exporter)
36     *
37     * Okay, 'eval' and 'create_function' are alternatives, but i'm
38     * still looking for something that would let us manipulate the
39     * symbol table.... (would also be a nice-to-have feature for
40     * mungling "other" symbol table entries, like variables
41     * and/or object references etc.)
42     *
43     * TODO: $php::EXPORT_OK = array('Dumper', 'session_register_safe', 'mkObject', 'is_hash', 'merge_to');
44     *
45     */
46     // this is (and will probably always be) required by the "Exporter"
47     function &Dumper() {
48     $args = func_get_args();
49     // shrink array to single item?
50     //if (sizeof($args) == 1) { $args = $args[0]; }
51     php::array_shrink($args);
52     return php::Dumper($args);
53     }
54    
55     // these could be refactore using Exporter proposal below,
56     // which just does this code at runtime via eval
57     //function &session_register_safe() { return php::session_register_safe(func_get_args()); }
58     //function &is_hash() { return php::is_hash(func_get_args()); }
59     //function &loadModule() { return php::loadModule(func_get_args()); }
60     //function &mkObject() { return php::mkInstance(func_get_args()); }
61    
62    
63     //exit;
64    
65     // yes!
66     php::export_symbols();
67    
68    
69    
70     /**
71 joko 1.4 * --- php extension functions living in the php:: namespace
72 joko 1.1 *
73 joko 1.3 * <pre>
74     * x php::Dumper
75     * x php::session_register_safe
76     * x php::array_init
77     * x php::is_hash
78     * x php::array_join_merge
79     * o php::merge
80     * o php::merge_to
81     * x php::loadModule
82     * x php::mkInstance
83     * </pre>
84     *
85     * @author Andreas Motl <andreas.motl@ilo.de>
86     * @copyright (c) 2003 - All Rights reserved.
87     * @license GNU LGPL (GNU Lesser General Public License)
88     *
89     * @link http://www.netfrag.org/~joko/
90     * @link http://www.gnu.org/licenses/lgpl.txt
91     *
92     * @package org.netfrag.glib
93     * @name php
94     *
95     * @todo
96     * <pre>
97     * Todo:
98     *
99     * o establish mkInstance here (move from DesignPattern::Object::mkObject)
100     * o establish loadModule here (move from DesignPattern::Object::loadModule)
101     *
102     * Ideas:
103     * o php::create_redirector_function('func', array( type => 'lamba|function|method', name => 'Abc::do_xyz') )
104     * o php::create_redirector_method('class|obj_ref', 'method', $target)
105     * o php::export_symbol(from, to) (maybe solves above two)
106     * </pre>
107     *
108 joko 1.1 */
109     class php {
110    
111    
112     // Exporter proposal
113    
114     // does (e.g.) Exporter::export_symbol('php', 'loadModule', array( php_function => 'loadModule' ));
115     // (or) Exporter::export_symbol('php', 'mkInstance', array( php_function => 'mkObject' ));
116     // -> just all from EXPORT_OK
117    
118     function export_symbols() {
119    
120     $symbols = func_get_args();
121     php::array_shrink($symbols);
122    
123     global $PHP_EXTENSIONS_EXPORT;
124     //print Dumper($PHP_EXTENSIONS_EXPORT);
125     //exit;
126    
127     if (is_array($PHP_EXTENSIONS_EXPORT)) {
128     //if (defined('EXPORT_OK')) {
129     //print EXPORT_OK . "<br/>";
130     //$symbols = split(' ', EXPORT_OK);
131     //foreach ($php->EXPORT_OK as $symbol) {
132     /*
133     foreach (EXPORT_OK as $symbol) {
134     print "exporting: $symbol<br/>";
135     Exporter::export_symbol('php', $symbol, array( php_function => $symbol ));
136     }
137     */
138    
139     $symbols = php::array_join_merge($PHP_EXTENSIONS_EXPORT, $symbols);
140    
141     php::loadModule('Exporter');
142     if (class_exists('Exporter')) {
143     Exporter::export_symbols('php', $symbols);
144     }
145    
146     }
147    
148     }
149    
150     function Dumper() {
151     $arg_list = func_get_args();
152     $count = 1;
153    
154     // build dump by catching output of php's 'print_r'
155     // using php's output buffering functions
156     ob_start();
157     foreach ($arg_list as $arg) {
158     print_r($arg);
159     if (is_string($arg)) {
160     print "\n";
161     }
162     $count++;
163     }
164     $var_dump = ob_get_contents();
165     ob_end_clean();
166    
167     //print "mode: " . $this->Dumper_mode . "<br/>";
168     //if ($this->Dumper_mode == HTML) {
169     $var_dump = str_replace("\n", '<br/>', $var_dump);
170     $var_dump = str_replace(" ", '&nbsp;', $var_dump);
171     //}
172    
173     //if (sizeof($args) == 1) { $var_dump .= '<br/>'; }
174    
175     return $var_dump;
176     }
177    
178     function session_register_safe($varname) {
179     if (!session_is_registered($varname)) {
180     session_register($varname);
181     return 1;
182     }
183     }
184    
185     // -------------------------------------------------
186     // array initializer
187     // initializes passed variable (taken by reference) with an empty array
188     // does this only if it doesn't exist yet or initialization is explicitely requested ($clear = 1)
189     function array_init(&$var, $clear = 0) {
190     if (!is_array($var) || $clear) { $var = array(); }
191     }
192    
193     // from: php.net - http://www.php.net/manual/en/function.array-merge-recursive.php
194 joko 1.2 function is_hash( $var = null ) {
195 joko 1.1 if( is_array( $var ) ) {
196     $keys = array_keys( $var );
197     $all_num = true;
198     for( $i=0; $i<count($keys); $i++ )
199     if( is_string($keys[$i] ) ) return true;
200     }
201     return false;
202     }
203    
204     // from: php.net - http://www.php.net/manual/en/function.array-merge-recursive.php
205     function array_join_merge( $arr1, $arr2 ) {
206     if( is_array( $arr1 ) and is_array( $arr2 ) ) {
207     // the same -> merge
208     $new_array = array();
209    
210     if( php::is_hash( $arr1 ) and php::is_hash( $arr2 ) ) {
211     // hashes -> merge based on keys
212     $keys = array_merge( array_keys( $arr1 ), array_keys( $arr2 ) );
213     foreach( $keys as $key ) {
214     $new_array[$key] = php::array_join_merge( $arr1[$key], $arr2[$key] );
215     }
216     } else {
217     // two real arrays -> merge
218     $new_array =
219     array_reverse(array_unique(array_reverse(array_merge($arr1,$arr2))));
220     }
221    
222     return $new_array;
223     } else {
224     // not the same ... take new one if defined, else the old one stays
225     return $arr2 ? $arr2 : $arr1;
226     }
227     }
228    
229    
230     // TODO:
231     // o refactor to the php:: namespace?
232     // o PEAR::???
233     // x rename mkObject to mkInstance
234     // x rename loadModule? let it like is.... (suggestions? loadPackage?)
235     // o enhance loadModule: make it possible to load packages from anywhere?! #?)&%$
236    
237     function namespace2filename($nsName) {
238     if ($filename = str_replace('::', '/', $nsName)) {
239     return $filename;
240     }
241     }
242    
243     function loadModule($namespacedClassname, $options = null) {
244    
245     if (DEBUG_PHP_EXTENSIONS == 1) {
246     print "php::loadModule: " . Dumper($namespacedClassname);
247     }
248     if (LOG_PHP_EXTENSIONS == 1) {
249     php::append_log( "php::loadModule( $namespacedClassname )" );
250     }
251    
252     if ($filename = php::namespace2filename($namespacedClassname)) {
253    
254     if (is_array($options)) {
255     $extension = $options[extension];
256     } elseif ($options) {
257     $extension = $options;
258     } else {
259     $extension = 'php';
260     }
261    
262     $filename .= ".$extension";
263    
264     // V1: just require
265     //require_once($filename);
266    
267     // V2: check file for existance (didn't work!!! problem with path-style conversion regarding platform running on?)
268     /*
269     if (file_exists($filename)) {
270     require_once($filename);
271     } else {
272     //user_error("Could not load module '$namespacedClassname', file '$filename' does not exist.");
273     }
274     */
275    
276     // V3: wrapped through eval (weird)
277     /*
278     $evalstring = "return include_once('$filename');";
279     $result = eval($evalstring);
280     if (!$result) {
281     user_error("DesignPattern::Object: Could not load module '$namespacedClassname', file '$filename' does not exist.");
282     return;
283     }
284     */
285    
286     // V4: just include
287     //define ("WARNING", E_USER_NOTICE);
288     //error_reporting(E_USER_WARNING);
289     //error_reporting(E_ALL);
290     //error_reporting(E_CORE_ERROR);
291     //set_error_handler(array('php::error_handler_2'));
292    
293     //set_error_handler('php_error_handler');
294     // TODO: do stack-backtracing here to determine function called two or three levels before!!!
295     //print "file: $filename<br/>";
296     if (!include_once($filename)) {
297     $msg = "php::loadModule error: Could not load module '$namespacedClassname', file '$filename' does not exist.";
298     user_error($msg);
299     php::append_log($msg, PEAR_LOG_ERR);
300     //trigger_error($msg);
301     //print "msg: $msg<br/>";
302     return;
303     }
304     //restore_error_handler();
305    
306     //exit;
307    
308     return 1;
309     }
310     }
311    
312    
313     function &mkComponent() {
314    
315     // argument handling - perl style
316 joko 1.2 $arg_list = &func_get_args();
317 joko 1.1
318     // trace
319     //print "php::mkInstance: " . Dumper($arg_list);
320     //exit;
321    
322     // patch arglist if all arguments are passed in as a single array
323     if (sizeof($arg_list) == 1 && is_array($arg_list[0])) {
324 joko 1.2 $arg_list = &$arg_list[0];
325 joko 1.1 }
326    
327     //print "arg_list: $arg_list<br/>";
328     $namespacedClassname = array_shift($arg_list);
329    
330     // debug
331     if (DEBUG_PHP_EXTENSIONS == 1) {
332     print "php::mkComponent: $namespacedClassname<br/>";
333     }
334     if (LOG_PHP_EXTENSIONS == 1) {
335     php::append_log( "php::mkComponent( $namespacedClassname )" );
336     }
337    
338     $classname = $namespacedClassname;
339     $filename = $namespacedClassname;
340     $load_module_options = null;
341    
342     if (strstr($namespacedClassname, '_')) {
343     //print "mkObject: unallowed character in namespaced classname: '_' ($namespacedClassname)<br/>";
344     //return;
345     }
346    
347     if (strstr($namespacedClassname, '.')) {
348     //print "mkObject: unallowed character in namespaced classname: '_' ($namespacedClassname)<br/>";
349     //return;
350     $parts = split('\.', $namespacedClassname);
351     $filename = $parts[0];
352     $extension = $parts[sizeof($parts) - 1];
353     $load_module_options = array( extension => $extension );
354     }
355    
356    
357     // trace
358     //print "mkObject: $classname<br>";
359     //print "file: $filename<br>";
360    
361     // build native class name from namespaced one
362     $classname = str_replace('::', '_', $classname);
363     $classname = str_replace('/', '_', $classname);
364    
365     // load class-file
366     if (!class_exists($classname)) {
367     php::loadModule($filename, $load_module_options);
368     }
369    
370     // instantiate object
371     $attributes = $arg_list;
372     // V0:
373     //$obj = new $classname($attributes);
374     // V1:
375     //$obj = new DesignPattern_Bridge($classname, $attributes);
376     // V2:
377     $obj = php::mkInstance($classname, $attributes);
378    
379     // constructor autocall - if possible
380     // FIXME: take care for side-effects!!!
381     /*
382     if (method_exists($obj, 'constructor')) {
383     $obj->constructor();
384     }
385     */
386    
387     // return instance
388     return $obj;
389    
390     }
391    
392     // from: http://www.php.net/manual/en/function.method-exists.php
393     function class_has_method($className, $methodName) {
394     $bool_exists = (in_array(strtolower($methodName), get_class_methods($className)));
395     return $bool_exists;
396     }
397    
398     // down: array( item ) => item
399     function &array_shrink(&$array) {
400     // shrink array to single item? yes!
401     if (is_array($array) && !php::is_hash($array) && (sizeof($array) == 1)) { $array = $array[0]; }
402     return $array;
403     }
404    
405     function append_log($message, $level = PEAR_LOG_DEBUG) {
406     static $Class_Logger_loaded;
407     static $Class_Logger_instance;
408     if (!$Class_Logger_loaded) {
409     $Class_Logger_loaded++;
410     //print "LOAD<br/>";
411     php::loadModule('Class::Logger');
412     }
413     if (class_exists('Class_Logger')) {
414     //$Class_Logger_instance = new Class_Logger();
415     $Class_Logger_instance = php::mkComponent('Class::Logger');
416     //print "YAI<br/>";
417     //Class_Logger::log($message);
418     $Class_Logger_instance->log($message, $level);
419     } else {
420     // FIXME! pre-logger log-messages (two or three):
421     // [PEAR_LOG_DEBUG] php::loadModule( Class::Logger )
422     // [PEAR_LOG_DEBUG] php::loadModule( DesignPattern::AbstractClass )
423     //print "[$level] $message" . "<br/>";
424     }
425     }
426    
427 joko 1.2 function &mkInstance($classname, $attributes = array()) {
428 joko 1.1
429     $oo = is_object($this);
430    
431     // autocall constructor?
432     if ($oo) {
433     //print Dumper($this);
434     //exit;
435     //print "this: $this<br/>";
436     //print "parent: $parent<br/>";
437     // V1:
438     //parent::constructor();
439     // V2:
440     //call_user_func('parent::constructor');
441     // V3:
442     //call_user_func(array($this, 'constructor'));
443     if (method_exists($this, 'constructor')) {
444     //print "YAI<br/>";
445     //call_user_func(array($this, 'constructor'));
446     }
447     }
448    
449     if ($oo) {
450     //$this->log( get_class($this) . "->mkInstance( classname $classname )" );
451     //Class_Logger::log( get_class($this) . "->mkInstance( classname $classname )" );
452     } else {
453     //php::append_log( "php::mkInstance( classname $classname )" );
454     }
455    
456     if (isset($attributes)) {
457     //print Dumper($attributes);
458    
459     /*
460     // pass single argument 1:1
461     if (count($attributes) == 1) {
462     $attributes_merged = $attributes[0];
463    
464    
465    
466     // pass hash 1:1
467     } elseif (is_hash($attributes)) {
468     $attributes_merged = $attributes;
469    
470     } else {
471     $attributes_merged = $attributes;
472     }
473     */
474    
475     $args_pass = array();
476     for ($i=0; $i<=count($attributes); $i++) {
477 joko 1.2 array_push($args_pass, '&$attributes[' . $i . ']');
478 joko 1.1 }
479    
480     $arg_string = join(', ', $args_pass);
481    
482     /*
483     // merge entries of numerical indexed arrays together into one hash
484     } else {
485     $attributes_merged = array();
486     foreach ($attributes as $entry) {
487     $attributes_merged = array_merge($attributes_merged, $entry);
488     }
489     }
490     */
491    
492     if (!class_exists($classname)) {
493     user_error("Class '$classname' doesn't exist.");
494     return;
495     }
496    
497     //print Dumper($attributes_merged);
498     //print Dumper($attributes);
499     //$instance = new $classname($attributes_merged);
500     //$instance = new $classname($attributes[0]);
501     $evalstr = 'return new $classname(' . $arg_string . ');';
502    
503     //print "eval: $evalstr<br/>";
504    
505     $instance = eval($evalstr);
506     //print $evalstr . "<br>";
507     } else {
508     $instance = new $classname;
509     }
510     //$this->log("ok");
511     return $instance;
512     }
513    
514     // up: string -> array
515     function array_cast_safe(&$array_or_not) {
516     if (!is_array($array_or_not)) {
517     $array_or_not = array($array_or_not);
518     //print Dumper($array_or_not);
519     //exit;
520     }
521     }
522    
523     // To return all ancestors class of an object
524     // from: http://www.php.net/manual/en/function.get-parent-class.php
525     function get_ancestors_class($classname) {
526     $father = get_parent_class($classname);
527     if ($father != "") {
528     $ancestors = php::get_ancestors_class($father);
529     $ancestors[] = $father;
530     }
531     return $ancestors;
532     }
533    
534     // ------ override/expand php's 'include_path' setting ------
535     function add_libpath($paths) {
536    
537     if (!is_array($paths)) {
538     $paths = array($paths);
539     }
540     array_push($paths, ini_get("include_path"));
541    
542     // determine OS
543     $os = 'linux';
544     if (stristr($_SERVER["SERVER_SOFTWARE"], 'win32')) {
545     $os = 'windows';
546     }
547    
548     $path_delimiter = ':';
549     // change path-delimiter for win32
550     if ($os == 'windows') { $path_delimiter = ';'; }
551     // build new 'include_path'-string
552     $path_new = join($path_delimiter, $paths);
553     ini_set("include_path", $path_new);
554     }
555    
556     // from: http://www.php.net/manual/en/function.is-subclass-of.php
557     function is_subclass($child, $parent) {
558     if (is_string($child)) {
559     do {
560     $child = get_parent_class($child);
561     if (!$child) return false;
562     //} while ($child == $parent);
563     } while ($child != $parent);
564     return true;
565     } else {
566     return is_subclass_of($child, $parent);
567     }
568     }
569    
570    
571     }
572    
573     //function error_handler($errno, $errstr, $errfile, $errline) {
574     function php_error_handler() {
575     //print "ERROR!<br/>";
576     $error_raw = func_get_args();
577    
578     //print Dumper($error_raw);
579    
580     $error = array(
581     'level' => $error_raw[0],
582     'message' => $error_raw[1],
583     'file' => $error_raw[2],
584     'line' => $error_raw[3],
585     'context' => &$error_raw[4],
586     'object_context' => &$error_raw[4][this],
587     );
588     $error[component] = $error[object_context]->_component_name;
589    
590     //$output_order = array( 'message', 'component', 'file', 'line', 'level' );
591     $output_order = array( 'message', 'file', 'line' );
592    
593     /*
594     $level = $error[0];
595     $context = &$error[4];
596     $cc = &$context['this'];
597     */
598    
599    
600     //print Dumper($context);
601     //print Dumper($cc);
602     //print Dumper($cc->_component_name);
603    
604     // by level
605     //$do_trace = ($level <= 5);
606    
607     //$c_name = $context['this']['_component_name'];
608    
609     //print "c_error: $c_name<br/>";
610    
611     // if component
612     //$do_trace = isset($context[this][_component_name]);
613     //$do_trace = isset($context->this[_component_name]);
614     //$do_trace = isset($cc->_component_name);
615     $do_trace = isset($error[component]);
616    
617     //$do_trace = 1;
618    
619     //print Dumper($context);
620    
621     if ($do_trace) {
622    
623     //print php::Dumper($error);
624     //exit;
625    
626     //print "<hr/><b><font color=\"red\">ERROR:</font></b><br/>";
627     print "<b><font color=\"red\">ERROR:</font></b><br/> ";
628    
629     foreach ($output_order as $key) {
630     print "<b>$key:</b> $error[$key]<br/>";
631     }
632    
633     }
634    
635     }
636    
637    
638     ?>

MailToCvsAdmin">MailToCvsAdmin
ViewVC Help
Powered by ViewVC 1.1.26 RSS 2.0 feed