PHP code example of chuchiy / phpex

1. Go to this page and download the library: Download chuchiy/phpex library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

chuchiy / phpex example snippets



= new \Pex\Pex; 
//install plugin for result jsonize and inject a console logger
$pex->install(function($run){
    return function($cycle) use ($run) {
        $cycle->register('log', function($c) {
            return function($msg) { error_log($msg, 4); };
        });
        $r = $run($cycle);
        return ($r instanceof stdClass)?json_encode($r):$r;
    };
});

//routing with anonymous function
$pex->attach('/console')->get('/send/<msg>', function($cycle){
    call_user_func($cycle->log, "recv msg: {$cycle['msg']}");
    return (object)['ok'=> True];
});

//handler class use method annotation routing
class PexHandler {

    /** 
     * @get('/hello/<name>')
     */
    public function hello($cycle) {
        return 'hello ' . $cycle['name'];
    }

    /**
     * @route('/get')
     */
    public function getId($cycle) {
        return (object)['id'=>$cycle->want('id'), 'name'=>$cycle->get('name', 'foo')];
    }
};
$pex->attach('/', 'PexHandler');

$pex->serve();

$pex->get('/path/to/a', function($c){return 'a'});
$pex->get('/path/to/b', function($c){return 'b'});

$pex->attach('/path-at/')->get('/a', function($c){
    return 'a';
})->post('/b', function($c){
    return 'b';
})->with(function($run){
    return funcion($c) use ($run) {
        $r = $run($c);
        return (is_string($r))?strtoupper($r):$r;
    };
});

$pex->attach('/api/', '\NS\Api');
$pex->attach('/site/', '\NS\Site');

class Api {

    public function __invoke($route) {
        $route->post('delete', [$this, 'delete']);
    }

    public function delete($cycle) {
        return ['ok'=>True];
    }

    /**
     * @post('/create')
     */
    public function create($cycle) {
        return ['id'=>uniqid()];
    }

    /**
     * @get('/list')
     */
    public function list($cycle) {
        return ['list'=>range(0, 10)];
    }

}

//demonstration proces chain build
$callable = $plugin1($plugin2($plugin3($handler)));
$r = $callable($cycle);


function jsonize($run) {
    return function($cycle) use ($run) {
        //run the inner callable
        $r = $run($cycle);
        return ($r instanceof stdClass)?json_encode($r):$r;
    };
}

$pex = new \Pex\Pex;
$pex->install('global_plugin');
$pex->install('global_plugin2');

$pex->post('/foo', 'foo_handler')->get('/bar', 'bar_handler')->with('awesome_plugin');

class Foo {

    public function __invoke($route) {
        $route->install('foo_plugin')
    }

    ...
    ..
}


class Foo {

    public function __invoke($route) {
        $route->bindAnnotation('view', new \Pex\Plugin\Templater(__DIR__));
    }

    /**
     * @get('/bar')
     * @view('bar.tpl')
     * @custhdr('x-author', 'pex')
     * @custhdr('x-site', 'test')
     */
    public function bar($cycle) {
        return [];
    }

}
$pex->attach('/', 'Foo');
//bind a high-order function to annotation command custhdr
//$name = 'custhdr', $args = ['x-...', '....']
$pex->bindAnnotation('custhdr', function($name, $args){
    //return a plugin
    return function($run) use ($name, $args) {
        return function($cycle) use ($run, $name, $args) {
            $r = $run($cycle);
            $cycle->reply()[$args[0]] = $args[1];
            return $r;
        };
    };
});


$cnt = 0;
$cycle->inject('counter', function($cycle) use (&$cnt) {
    return ++$cnt;
});

$cycle->register('counter2', function($cycle) use (&$cnt) {
    return ++$cnt;
});

var_dump($cycle->counter); //will output 1
var_dump($cycle->counter); //will output 2
var_dump($cycle->counter2); //will output 1
var_dump($cycle->counter2); //will output 1

$request = $cycle->request();  //return a PSR-7 http request

$ua = $cycle->client()->userAgent();

$cycle->reply()->setHeader('content-type', 'text/plain')
$cycle->reply()['x-author'] = 'Pex';

$writer = $cycle(200, ['x-site'=>'test']);
$writer('body');
//return a PSR-7 http response. you can only get response after $cycle($status, $headers) is called.
$response = $cycle->response(); 


$pex->install(new \Pex\Plugin\CatchHttpException);
    ...
    ...
$pex->get('/redir', function($cycle){
    //http page redirect
    $cycle->interrupt(302, ['Location'=>$cycle->want('cont')]);
})

$pex->bindAnnotation('view', new \Pex\Plugin\Templater(__DIR__));
$pex->bindAnnotation('twig', new \Pex\Plugin\TwigPlugin(__DIR__, sys_get_temp_dir().'/twig/'));

class Page {

    public function __invoke($route) {
        $route->install(function($run) {
            return function($cycle) use ($run) {
                $r = $cycle($run);
                $r['menu'] = ['a', 'b', 'c']
                $r['user'] = 'pex';
                return $r;
            };
        });
    }

    /**
     * @view('header.php', 'main.php', 'footer.php')
     * @get('/test')
     */
    public function test($cycle) {
        return ['name'=>'test'];
    }

    /**
     * @twig('hello.html')
     * @get('/hello')
     */
    public function hello($cycle) {
        return ['name'=>'hello']
    }
}


= new \Pex\Pex; 
//inject timer
$pex->install(function($run){
    return function($cycle) use ($run) {
        $start = microtime(true);
        $r = $run($cycle);
        //set reply header
        $cycle->reply()['x-proc-msec'] = round((microtime(true)-$start)*1000, 3);
        return $r;
    }
});

$pex->install(function($run){
    return function($cycle) use ($run) {
        $cycle->register('db', function($c) {
            return new \PDO('sqlite::memory:');
        });
        return $run($cycle);
    }
});

function jsonInput($run) {
    return function($cycle) use ($run) {
        //$c is the latest cycle object when $cycle->input is first called
        $cycle->register('input', function($c) {
            return json_decode((string)$c->request()->getBody(), true);
        });
        return $run($cycle);
    };
}

$cycle->client()->userAgent(); //get request user-agent
$cycle->client()->contentType(); //get request content-type
$cycle->client()->isAjax(); //whether the request is ajax request or not
$cycle->client()->publicIp(); //get the most likely public ip of client
$cycle->client()->redirect($url); //redirect client to $url
$cycle->client()->referer(); //get request referer


class Jsonize extends \Pex\Plugin\BasePlugin 
{
    protected function apply($cycle, $run)
    {
        $r = $run($cycle);
        if((is_array($r) and array_keys($r) !== range(0, count($r) - 1)) or (is_object($r) and $r instanceof \stdClass)) {
            $cycle->reply()['Content-Type'] = 'application/json; charset=utf-8';
            $r = json_encode($r, JSON_UNESCAPED_UNICODE);
        }
        return $r;
    }    
}


class AddHeader extends \Pex\Plugin\HighorderPlugin
{
    protected function apply($cycle, $run, $name, $args)
    {
        $r = $run($cycle);
        $cycle->reply()[$args[0]] = $args[1];
        return $r;        
    }
}

$pex->bindAnnotation('custhdr', new AddHeader);

class A {
    /**
     * @get('/test')
     * @custhdr('x-extra', 'foobar')
     */
    public function($cycle) {
        return 'abc';
    }
}

$pex->bindAnnotation('view', new \Pex\Plugin\Templater(__DIR__));

class Page {
    
    /**
     * use view command without parameters will only inject template instance
     * @get('/test')
     * @view
     */
    public function render($cycle) {
        return $cycle->view->render(['name'=>'foobar'], 'test.php');
    }
}

function go2login($cycle) {
    $cycle->client()->redirect($cycle->mountpoint() . 'login'); //will redirect to /app/login
}
$pex->attach('/app/')->get('/auth', 'go2login');

$val = $cycle->want('foo'); //throw InvalidArgumentException if parameter not found
$val = $cycle->get('foo'); //return null if parameter not found
$val = $cycle->get('foo', 'dftval');
$val = $cycle['foo'];
isset($cycle['foo']);

//return file stream
function fileStream($cycle) {
    return fopen('foo.bar', 'r');
}
//generator
function fileStream($cycle) {
    $fp = fopen('foo.bar', 'r');
    while (!feof($fp)) {
        yield fread($fp, 8192);
    }
}
//write to response body
function fileWriter($cycle) {
    $writer = $cycle();
    $fp = fopen('foo.bar', 'r');
    while (!feof($fp)) {
        $writer(fread($fp, 8192));
    }    
}
nginx
    ...
    location / {
            fastcgi_param SCRIPT_FILENAME /var/www/index.php;
            fastcgi_pass ...;
            ...
            ...
    }
    ...