Skip to content

Instantly share code, notes, and snippets.

@k-holy
Created January 31, 2012 16:28
Show Gist options
  • Save k-holy/1711438 to your computer and use it in GitHub Desktop.
Save k-holy/1711438 to your computer and use it in GitHub Desktop.
SilexからSlimに書き換えてみたサンプル
<?php
return function($trace) {
$varFormatter = function($var) {
if (is_null($var)) {
return 'NULL';
}
if (is_int($var)) {
return sprintf('Int(%d)', $var);
}
if (is_float($var)) {
return sprintf('Float(%F)', $var);
}
if (is_string($var)) {
return sprintf('"%s"', $var);
}
if (is_bool($var)) {
return sprintf('Bool(%s)', $var ? 'true' : 'false');
}
if (is_array($var)) {
return 'Array';
}
if (is_object($var)) {
return sprintf('Object(%s)', get_class($var), $var);
}
return sprintf('%s', gettype($var));
};
$stack = array();
foreach ($trace as $i => $t) {
$args = '';
if (isset($t['args']) && !empty($t['args'])) {
$args = implode(', ', array_map(function($arg) use ($varFormatter) {
if (is_array($arg)) {
$vars = array();
foreach ($arg as $key => $var) {
$vars[] = sprintf('%s=>%s',
$varFormatter($key), $varFormatter($var));
}
return sprintf('Array[%s]', implode(', ', $vars));
}
return $varFormatter($arg);
}, $t['args']));
}
$stack[] = sprintf('#%d %s(%d): %s%s%s(%s)',
$i,
(isset($t['file' ])) ? $t['file' ] : '',
(isset($t['line' ])) ? $t['line' ] : '',
(isset($t['class' ])) ? $t['class' ] : '',
(isset($t['type' ])) ? $t['type' ] : '',
(isset($t['function'])) ? $t['function'] : '',
$args);
}
return $stack;
};
<?php
/**
* 系図管理 フロントコントローラ Silex版
*
* @copyright 2011 k-holy <[email protected]>
* @author [email protected]
* @license http://www.opensource.org/licenses/mit-license.php The MIT License (MIT)
*/
namespace Acme;
require_once realpath(__DIR__ . '/silex.phar');
require_once realpath(__DIR__ . '/vendor/redbean/rb.php');
use Silex\Application;
use Silex\Provider\SessionServiceProvider;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Holy\Silex\Provider\PhpTalServiceProvider;
use Holy\RedBean\ModelFormatter;
use Acme\InputValidationException;
use Acme\DbUtil;
const CSRF_TOKEN_NAME = 'AEg9GE5#4ZyPY$fd';
const DEBUG = true;
// Silex Application
$app = new Application();
$app['debug'] = DEBUG;
$app['autoloader']->registerNamespace('Holy' ,
realpath(__DIR__ . '/vendor/k-holy/src'));
$app['autoloader']->registerNamespace('Acme',
realpath(__DIR__ . '/app/src'));
$app->register(new SessionServiceProvider());
$app->register(new PhpTalServiceProvider(), array(
'phptal.class_path' => realpath(__DIR__ . '/vendor/phptal'),
'phptal.options' => array(
'templateRepository' => realpath(__DIR__ . '/views'),
),
));
// RedBean
\R::addDatabase('default',
sprintf('sqlite:%s', realpath(__DIR__ . '/app/data/keizu.sqlite')),
null, null, true);
\R::selectDatabase('default');
\R::debug(DEBUG);
\RedBean_ModelHelper::setModelFormatter(new ModelFormatter('Acme', null, 'Model'));
// Error handler
$app->error(function(\Exception $e, $code) use ($app) {
$traceFormatter = include realpath(__DIR__ . '/app/src/closure.trace_formatter.php');
$app['phptal']->set('title', 'エラー');
$app['phptal']->set('error', (DEBUG)
? sprintf("Fatal Error: Uncaught exception '%s' with message '%s' in %s:%d\nStack trace:\n%s\n thrown in %s on line %d",
get_class($e),
$e->getMessage(),
$e->getFile(),
$e->getLine(),
implode("\n", $traceFormatter($e->getTrace())),
$e->getFile(),
$e->getLine())
: null);
$message = 'サーバー内部でエラーが発生しました';
$status = 500;
if ($e instanceof \Symfony\Component\HttpKernel\Exception\HttpExceptionInterface) {
switch ($code) {
case 403:
$message = 'お探しのページは表示できません';
$status = 403;
break;
case 404:
$message = 'お探しのページは見つかりませんでした';
$status = 404;
break;
case 405:
$message = '不正なアクセスです';
$status = 405;
break;
}
}
$app['phptal']->set('message', $message);
return new Response($app['phptal']->setTemplate('error.html')->execute(),
$status);
});
// Before filter
$app->before(function(Request $request) use($app) {
$app['phptal']->set('REQUEST_URI', $request->getRequestUri());
$app['phptal']->set('BACK_URI' , $request->query->get('back'));
if ($app['session']->hasFlash('message')) {
$flash = array(
'message' => $app['session']->getFlash('message'),
);
$app['session']->removeFlash('message');
$app['phptal']->set('flash', $flash);
}
});
//----------------------------------------------------------------------------
// トップページ
//----------------------------------------------------------------------------
$app->get('/',
function(Application $app, Request $request)
{
$app['phptal']->set('title', 'トップページ');
return $app['phptal']->setTemplate('index.html')->execute();
});
//----------------------------------------------------------------------------
// 人物一覧
//----------------------------------------------------------------------------
$app->get('/profiles/',
function(Application $app, Request $request)
{
$profile = \R::dispense('profiles');
$surname = $request->query->get('surname');
$name = $request->query->get('name');
$profiles = $profile->search(array(
'surname' => $surname,
'name' => $name,
));
$app['phptal']->set('surname', $surname);
$app['phptal']->set('name' , $name);
$app['phptal']->set('items' , $profiles);
$app['phptal']->set('title' , '人物一覧');
return $app['phptal']->setTemplate('profiles/index.html')->execute();
});
//----------------------------------------------------------------------------
// 人物登録
//----------------------------------------------------------------------------
$app->match('/profiles/register',
function(Application $app, Request $request)
{
$sessionId = $app['session']->getId();
$profile = \R::dispense('profiles');
switch($request->getMethod()) {
case 'POST':
$profile->import($request->request->all(),
$profile->getFieldNames());
if ($request->get(CSRF_TOKEN_NAME) === $sessionId) {
try {
\R::store($profile);
} catch (InputValidationException $ex) {
$app['phptal']->set('errors', $ex->getErrors());
break;
}
$app['session']->setFlash('message', '人物情報を登録しました。');
return $app->redirect('/profiles/', 303);
}
break;
}
$app['phptal']->set('token', array(
'name' => CSRF_TOKEN_NAME,
'value' => $sessionId,
));
$app['phptal']->set('data' , $profile);
$app['phptal']->set('title', '人物登録');
return $app['phptal']->setTemplate('profiles/edit.html')->execute();
});
//----------------------------------------------------------------------------
// 人物編集
//----------------------------------------------------------------------------
$app->match('/profiles/{id}/modify',
function(Application $app, Request $request, $id)
{
$sessionId = $app['session']->getId();
$profile = \R::load('profiles', $id);
if (empty($profile->id)) {
$app->abort(404, sprintf('Profile "%s" does no exist.', $id));
}
switch($request->getMethod()) {
case 'POST':
$profile->import($request->request->all(),
$profile->getFieldNames());
if ($request->get(CSRF_TOKEN_NAME) === $sessionId) {
try {
\R::store($profile);
} catch (InputValidationException $ex) {
$app['phptal']->set('errors', $ex->getErrors());
break;
}
$app['session']->setFlash('message', '人物情報を更新しました。');
return $app->redirect(($request->request->has('back'))
? $request->request->get('back')
: '/profiles/', 303);
}
break;
}
$app['phptal']->set('token', array(
'name' => CSRF_TOKEN_NAME,
'value' => $sessionId,
));
$app['phptal']->set('data' , $profile);
$app['phptal']->set('title', '人物編集');
return $app['phptal']->setTemplate('profiles/edit.html')->execute();
})->method('GET|POST')
->assert('id', '\d+');
$app->run();
<?php
/**
* 系図管理 フロントコントローラ Slim版
*
* @copyright 2011 k-holy <[email protected]>
* @author [email protected]
* @license http://www.opensource.org/licenses/mit-license.php The MIT License (MIT)
*/
namespace Acme;
require_once realpath(__DIR__ . '/vendor/slim/Slim/Slim.php');
require_once realpath(__DIR__ . '/vendor/redbean/rb.php');
require_once realpath(__DIR__ . '/vendor/k-holy/src/Holy/Loader.php');
use Holy\Silex\Provider\PhpTalServiceProvider;
use Holy\Silex\Provider\RedBeanServiceProvider;
use Holy\RedBean\ModelFormatter;
use Acme\InputValidationException;
use Acme\DbUtil;
const CSRF_TOKEN_NAME = 'AEg9GE5#4ZyPY$fd';
const DEBUG = true;
// Autoloader
spl_autoload_register(\Holy\Loader::getInstance()
->set('Holy' , realpath(__DIR__ . '/vendor/k-holy/src'))
->set('Acme' , realpath(__DIR__ . '/app/src'))
->set('Slim' , realpath(__DIR__ . '/vendor/slim'))
->set('PHPTAL', realpath(__DIR__ . '/vendor/phptal'))
, true, true);
// Application Exception
class HttpException extends \RuntimeException {}
// Slim
$app = new \Slim(array(
'debug' => DEBUG,
'session.flash_key' => 'Keizu.flash_key',
'view' => '\Holy\Slim\View\PhpTalView',
'templates.path' => realpath(__DIR__ . '/views'),
));
session_start();
// RedBean
\R::addDatabase('default',
sprintf('sqlite:%s', realpath(__DIR__ . '/app/data/keizu.sqlite')),
null, null, true);
\R::selectDatabase('default');
\R::debug(DEBUG);
\RedBean_ModelHelper::setModelFormatter(new ModelFormatter('Acme', null, 'Model'));
// Grobal Data
$data = array();
// Error handler
$app->error(function(\Exception $e) use ($app, &$data) {
$code = $e->getCode();
$data['title'] = 'エラー';
$data['message'] = 'サーバー内部でエラーが発生しました';
$status = 500;
if ($e instanceof HttpException) {
switch ($code) {
case 403:
$data['message'] = 'お探しのページは表示できません';
$status = 403;
break;
case 404:
$data['message'] = 'お探しのページは見つかりませんでした';
$status = 404;
break;
case 405:
$data['message'] = '不正なアクセスです';
$status = 405;
break;
}
}
$app->render('error.html', $data, $status);
});
// 404 Response
$app->notFound(
function() use ($app, &$data)
{
$data['title' ] = 'エラー';
$data['message'] = 'お探しのページは見つかりませんでした';
$app->render('error.html', $data, 404);
});
// Before dispatch hook
$app->hook('slim.before.dispatch', function() use ($app, &$data) {
$request = $app->request();
$data['REQUEST_URI'] = $request->getResourceUri();
$data['BACK_URI' ] = $request->get('back');
});
//----------------------------------------------------------------------------
// トップページ
//----------------------------------------------------------------------------
$app->get('/',
function() use ($app, &$data)
{
$data['title'] = 'トップページ';
$app->render('index.html', $data);
});
//----------------------------------------------------------------------------
// 人物一覧
//----------------------------------------------------------------------------
$app->get('/profiles/',
function() use ($app, &$data)
{
$request = $app->request();
$profile = \R::dispense('profiles');
$surname = $request->get('surname');
$name = $request->get('name');
$profiles = $profile->search(array(
'surname' => $surname,
'name' => $name,
));
$data['surname'] = $surname;
$data['name' ] = $name;
$data['items' ] = $profiles;
$data['title' ] = '人物一覧';
$app->render('profiles/index.html', $data);
});
//----------------------------------------------------------------------------
// 人物登録
//----------------------------------------------------------------------------
$app->map('/profiles/register',
function() use ($app, &$data)
{
$request = $app->request();
$sessionId = session_id();
$profile = \R::dispense('profiles');
switch($request->getMethod()) {
case 'POST':
$profile->import($request->post(),
$profile->getFieldNames());
if ($request->post(CSRF_TOKEN_NAME) === $sessionId) {
try {
\R::store($profile);
} catch (InputValidationException $ex) {
$data['errors'] = $ex->getErrors();
break;
}
$app->flash('message', '人物情報を登録しました。');
$app->redirect('/profiles/', 303);
}
break;
}
$data['token'] = array(
'name' => CSRF_TOKEN_NAME,
'value' => $sessionId,
);
$data['data' ] = $profile;
$data['title'] = '人物登録';
$app->render('profiles/edit.html', $data);
})->via('GET', 'POST');
//----------------------------------------------------------------------------
// 人物編集
//----------------------------------------------------------------------------
$app->map('/profiles/:id/modify',
function($id) use ($app, &$data)
{
$request = $app->request();
$sessionId = session_id();
$profile = \R::load('profiles', $id);
if (empty($profile->id)) {
$app->error(new HttpException(
sprintf('Profile "%s" does no exist.', $id), 404));
}
switch($request->getMethod()) {
case 'POST':
$profile->import($request->post(),
$profile->getFieldNames());
if ($request->post(CSRF_TOKEN_NAME) === $sessionId) {
try {
\R::store($profile);
} catch (InputValidationException $ex) {
$data['errors'] = $ex->getErrors();
break;
}
$app->flash('message', '人物情報を更新しました。');
$back = $request->get('back');
$app->redirect(isset($back) ? $back : '/profiles/', 303);
}
break;
}
$data['token'] = array(
'name' => CSRF_TOKEN_NAME,
'value' => $sessionId,
);
$data['data' ] = $profile;
$data['title'] = '人物編集';
$app->render('profiles/edit.html', $data);
})->via('GET', 'POST')
->conditions(array('id' => '\d+'));
$app->run();
<?php
/**
* PHP versions 5
*
* @copyright 2011 k-holy <[email protected]>
* @author [email protected]
* @license http://www.opensource.org/licenses/mit-license.php The MIT License (MIT)
*/
namespace Holy\Slim\View;
class PhpTalView extends \Slim_View
{
/**
* Render template
* @param string $template Path to template file relative to templates directory
* @return string Rendered template
* @throws RuntimeException If template does not exist
*/
public function render($template)
{
$phptal = new \PHPTAL();
$phptal->setTemplateRepository($this->getTemplatesDirectory());
foreach (array_keys($this->data) as $key) {
$phptal->set($key, $this->data[$key]);
}
echo $phptal->setTemplate($template)->execute();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment