Skip to content

Commit e5dcc4c

Browse files
committed
minor improvements to codegen
1 parent e78be9a commit e5dcc4c

File tree

1 file changed

+63
-59
lines changed

1 file changed

+63
-59
lines changed

demo/server/codegen.php

Lines changed: 63 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -13,83 +13,87 @@
1313
use PhpXmlRpc\Wrapper;
1414

1515
if (isset($_GET['generate']) && $_GET['generate']) {
16-
// CommentManager is the "xml-rpc-unaware" class, whose methods we want to make accessible via xml-rpc calls
17-
$cm = new CommentManager(sys_get_temp_dir() . "/comments.db");
18-
19-
// analyze the CommentManager instance and generate both code defining stub-methods and a dispatch map for the xml-rpc Server
20-
$w = new Wrapper();
21-
$code = $w->wrapPhpClass(
22-
$cm,
23-
array(
24-
'method_type' => 'nonstatic',
25-
'return_source' => true,
26-
// this is used to encode php NULL values into xml-rpc <NIL/> elements. If the partner does not support that, disable it
27-
'encode_nulls' => true,
28-
)
29-
);
30-
31-
// save the generated code in 3 files: a new class definition, holding all the stub methods, a file with the dispatch-map,
32-
// and a controller, to be accessed from the internet. This split allows to a) hand-edit the controller code if needed,
33-
// and b) later regenerate the stub-methods-holder and dispatch map without touching the controller.
34-
// NB: good security practices dictate that none of those files should be writeable by the webserver user account
35-
$targetClassFile = sys_get_temp_dir() . '/MyServerClass.php';
36-
$targetDispatchMapFile = sys_get_temp_dir() . '/myServerDispatchMap.php';
37-
$targetControllerFile = sys_get_temp_dir() . '/myServerController.php';
38-
39-
// generate a file with a class definition
40-
41-
// the generated code does not have an autoloader included - we need to add in one
42-
$autoloader = __DIR__ . "/_prepend.php";
43-
44-
file_put_contents($targetClassFile,
45-
"<?php\n\n" .
46-
"require_once '$autoloader';\n\n" .
47-
"class MyServerClass\n{\n\n"
48-
) || die('uh oh');
49-
50-
// we mangle a bit the code we get from wrapPhpClass to turn it into a php class definition instead of a bunch of functions
51-
52-
foreach ($code as $methodName => $methodDef) {
53-
file_put_contents($targetClassFile, ' ' . str_replace(array('function ', "\n"), array('public static function ', "\n "), $methodDef['source']) . "\n\n", FILE_APPEND) || die('uh oh');
54-
$code[$methodName]['function'] = 'MyServerClass::' . $methodDef['function'];
55-
unset($code[$methodName]['source']);
56-
}
57-
file_put_contents($targetClassFile, "}\n", FILE_APPEND) || die('uh oh');
16+
// *** NB do not do this in prod! The whole concept of code-generation is to do it offline using console scripts/ci/cd ***
17+
18+
// CommentManager is the "xml-rpc-unaware" class, whose methods we want to make accessible via xml-rpc calls
19+
$cm = new CommentManager(sys_get_temp_dir() . "/comments.db");
20+
21+
// analyze the CommentManager instance and generate both code defining stub-methods and a dispatch map for the xml-rpc Server
22+
$w = new Wrapper();
23+
$code = $w->wrapPhpClass(
24+
$cm,
25+
array(
26+
'method_type' => 'nonstatic',
27+
'return_source' => true,
28+
// this is used to encode php NULL values into xml-rpc <NIL/> elements. If the partner does not support that, disable it
29+
'encode_nulls' => true,
30+
)
31+
);
32+
33+
// save the generated code in 3 files: a new class definition, holding all the stub methods, a file with the dispatch-map,
34+
// and a controller, to be accessed from the internet. This split allows to a) hand-edit the controller code if needed,
35+
// and b) later regenerate the stub-methods-holder and dispatch map without touching the controller.
36+
// NB: good security practices dictate that none of those files should be writeable by the webserver user account
37+
$targetClassFile = sys_get_temp_dir() . '/MyServerClass.php';
38+
$targetDispatchMapFile = sys_get_temp_dir() . '/myServerDispatchMap.php';
39+
$targetControllerFile = sys_get_temp_dir() . '/myServerController.php';
40+
41+
// generate a file with a class definition
42+
43+
// the generated code does not have an autoloader included - we need to add in one
44+
$autoloader = __DIR__ . "/_prepend.php";
5845

59-
// generate separate files with the xml-rpc server instantiation and its dispatch map
46+
file_put_contents($targetClassFile,
47+
"<?php\n\n" .
48+
"require_once '$autoloader';\n\n" .
49+
"class MyServerClass\n{\n\n"
50+
) || die('uh oh');
6051

61-
file_put_contents($targetDispatchMapFile, "<?php\n\nreturn " . var_export($code, true) . ";\n");
52+
// we mangle a bit the code we get from wrapPhpClass to turn it into a php class definition instead of a bunch of functions
6253

63-
file_put_contents($targetControllerFile,
64-
"<?php\n\n" .
54+
foreach ($code as $methodName => $methodDef) {
55+
file_put_contents($targetClassFile, ' ' . str_replace(array('function ', "\n"), array('public static function ', "\n "), $methodDef['source']) . "\n\n", FILE_APPEND) || die('uh oh');
56+
$code[$methodName]['function'] = 'MyServerClass::' . $methodDef['function'];
57+
unset($code[$methodName]['source']);
58+
}
59+
file_put_contents($targetClassFile, "}\n", FILE_APPEND) || die('uh oh');
6560

66-
"// autoloader\n" .
67-
"require_once '$autoloader';\n\n" .
61+
// generate separate files with the xml-rpc server instantiation and its dispatch map
6862

69-
"require_once '$targetClassFile';\n\n" .
63+
file_put_contents($targetDispatchMapFile, "<?php\n\nreturn " . var_export($code, true) . ";\n");
64+
65+
file_put_contents($targetControllerFile,
66+
"<?php\n\n" .
67+
68+
"// class autoloader\n" .
69+
"require_once '$autoloader';\n\n" .
7070

7171
// NB: if we were running the generated code within the same script, the existing CommentManager instance would be
7272
// available for usage by the methods of MyServerClass, as we keep a reference to them within the variable Wrapper::$objHolder,
7373
// but since we are generating a php file for later use, it is up to us to initialize that variable with a
74-
// CommentManager instance:
74+
// CommentManager instance
75+
"// business logic setup\n" .
7576
"\$cm = new CommentManager(sys_get_temp_dir() . '/comments.db');\n" .
77+
"// save reference to the biz logic object so that it can be used by the code in the generated class\n" .
7678
"\PhpXmlRpc\Wrapper::holdObject('*', \$cm);\n\n" .
7779

78-
"\$dm = require_once '$targetDispatchMapFile';\n" .
79-
'$s = new \PhpXmlRpc\Server($dm, false);' . "\n\n" .
80-
'// NB: do not leave these 2 debug lines enabled on publicly accessible servers!' . "\n" .
81-
'$s->setOption(\PhpXmlRpc\Server::OPT_DEBUG, 2);' . "\n" .
82-
'$s->setOption(\PhpXmlRpc\Server::OPT_EXCEPTION_HANDLING, 1);' . "\n\n" .
83-
'$s->service();' . "\n"
84-
) || die('uh oh');
80+
"// the generated class implementing the json-rpc methods is not namespaced, load it explicitly\n" .
81+
"require_once '$targetClassFile';\n\n" .
82+
83+
"// load the dispatch map and feed it to the json-rpc server\n" .
84+
"\$dm = require_once '$targetDispatchMapFile';\n" .
85+
'$s = new \PhpXmlRpc\Server($dm, false);' . "\n\n" .
86+
'// NB: do not leave these 2 debug lines enabled on publicly accessible servers!' . "\n" .
87+
'$s->setOption(\PhpXmlRpc\Server::OPT_DEBUG, 2);' . "\n" .
88+
'$s->setOption(\PhpXmlRpc\Server::OPT_EXCEPTION_HANDLING, 1);' . "\n\n" .
89+
'$s->service();' . "\n"
90+
) || die('uh oh');
8591

8692
echo "Code generated";
8793
} else {
8894
// test that everything worked by running it in realtime (note that this script will return an xml-rpc error message if
8995
// run from the command line, as the server will find no xml-rpc payload to operate on)
9096

91-
// *** NB do not do this in prod! The whole concept of code-generation is to do it offline using console scripts/ci/cd ***
92-
9397
$targetControllerFile = sys_get_temp_dir() . '/myServerController.php';
9498
require $targetControllerFile;
9599
}

0 commit comments

Comments
 (0)