- 
                Notifications
    You must be signed in to change notification settings 
- Fork 1
Description
Scope of Change
This RFC suggests removing the special case handling necessary for the tools/ directory, e.g. in the build system, in possible future composer integration and so on.
Rationale
Make it easier to setup and embed the XP Framework.
Functionality
a) Setup
The goal is to remove special-case handling in build tools like our own xpbuild infrastructure and add-ons like the Maven build.
| Current | New | 
|---|---|
| 1. User invokes xprunner with class as arg | 1. -~- | 
| 2. xprunner startsphp /path/to/xp/tools/class-main.php. | 2. xprunner startsphp /path/to/runners/class-main.php | 
| 3. This installs CLI specific handling | 3. -~- | 
| 4. Then, lang.base.phpis loaded | 4. The class path from ./*.pthis searched for__xp.php, which contains the bootstrap code | 
| 5. The class path is compiled by scanning all *.pthfiles inuse= ...and the current directory | 5. The rest of the paths from use=...inside xp.ini is compiled to an include path and searched for__xp.phpif not previously found. | 
| 6. The bootstrap()method is invoked | 6. The bootstrapping code is executed | 
| 7. The class from the args is loaded | 7. -~- | 
| 8. Its static mainmethod is invoked with the rest of the args | 8. -~- | 
| 9. Exceptions are caught. | 9. -~- | 
| 10. The return value from main is returned as exit code | 10. -~- | 
This way, we can also support a local XP Framework requirement other than the per-system/per-user installation:
| Path files in . | XP Framework version used | 
|---|---|
| (no files) | The one in use=... | 
| A single file class.pth, with lib/mustache.xar and src/main/php | -~- | 
| A single file glue.pth with vendor/xp-framework/xp-core-6.0.0.xar | The one in the xar file | 
| Two files: class.pth (as above) and glue.pth (as above) | -~- | 
b) Via Apache
As a special case for running the XP Framework without runners but with the same entry point behavior, the following is necessary:
<VirtualHost ...>
  DocumentRoot ...
  RewriteEngine on
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteRule ^.*$ /web-main.php [PT,L]
</VirtualHost>
Now either use aliasing, symlink the web-main.php, or install the runners into the document root
ScriptAlias /web-main.php /path/to/global/xp/runners/setup/web-main.php
The framework version is determined by checking the *.pth files in the web root (defaults to {DOCUMENT_ROOT}/..). If you depend on xp-framework/core, this will be sufficient. This is the suggested way of doing it.
For legacy projects not depending on xp-framework/core, you can supply include_path=".:/path/to/xp/version" to provide a use path and use a double path separator for additional includes (e.g. include_path=".:/path/to/xp/version::/path/to/additional/includes:/path/to/even/more/includes")
c) Embedding
The goal is to be able to embed the XP Framework; or parts of it, in other applications. People may be interested in a userland MSSQL/Sybase protocol implementation instead of having to bug their devops to compile that for them; which is quite a hassle.
Since modern PHP applications are installed via Composer nowadays, we would adapt to that by providing a composer.json file and add the __xp.php bootstrapper to its files list. Path files (*.pth) are not necessary in this scenario, since Composer's autoload generator will include all the necessary files and provide a vendor/autoload.php which applications typically require. This will always use the locally required XP version, this is the way how composer was intended to work.
Taken from http://reactphp.org/:
// Composer semantics
require 'vendor/autoload.php';
// XP Framework here:
$conn= rdbms\DriverManager::getConnection('sybase://...');
// ReactPHP:
$app = function ($request, $response) use($conn) {
  $response->writeHead(200, ['Content-Type' => 'text/plain']);
  $response->end($conn->select('hello from world where language_id= 47')->next('hello'));
};
$loop = React\EventLoop\Factory::create();
$socket = new React\Socket\Server($loop);
$http = new React\Http\Server($socket, $loop);
$http->on('request', $app);
echo "Server running at http://127.0.0.1:1337\n";
$socket->listen(1337);
$loop->run();_TODO: Verify our autoloading doesn't conflict with other autoloaders!_
Composer and XP
The optional goal here could be to use composer to combine XP applications. The composer.json file needs to contain a VCS repository as long as we're not registered on packagist:
{
  "repositories": [
    {
      "type": "vcs",
      "url": "https://github.com/thekid/core"
    }
  ],
  "require" : {
    "xp-framework/core" : "dev-rfc/0287"
  }
}The we can execute install to download the dependency:
$ composer install
Loading composer repositories with package information
Installing dependencies (including require-dev) from lock file
- Installing xp-framework/core (dev-rfc/0287 ffd70d9)
  Cloning ffd70d9c33d1f20873ddbf2f7451683ff21938b0
Writing lock file
Generating autoload filesThis test program works as expected:
<?php
require('vendor/autoload.php');
\util\cmd\Console::writeLine('Hello World');To make classes work with the XP runners, simply add vendor/autoload.php to a local path file:
$ echo vendor/autoload.php > class.pthSecurity considerations
Speed impact
Dependencies
Related documents
https://github.com/thekid/composer
https://github.com/kiesel/xp-composer-installer