bearsunday / bear.package Goto Github PK
View Code? Open in Web Editor NEWA BEAR.Sunday framework component package
Home Page: https://packagist.org/packages/bear/package
License: MIT License
A BEAR.Sunday framework component package
Home Page: https://packagist.org/packages/bear/package
License: MIT License
d3.jsの技術をつかってアプリケーションの持つリソース情報、そのアスペクトを可視化する
it does not work after /dev/ debug web service.
SmartyProvider create Smarty instance.
class SmartyProvider implements Provide
{
use TmpDirInject;
use AppDirInject;
/**
* Return instance
*
* @return Smarty
*/
public function get()
{
$smarty = new Smarty;
$appPlugin = $this->appDir . '/vendor/libs/smarty/plugin/';
$frameworkPlugin = __DIR__ . '/plugin';
$smarty
->setCompileDir($this->tmpDir . '/smarty/template_c')
->setCacheDir($this->tmpDir . '/smarty/cache')
->setTemplateDir($this->appDir . '/Resource/View')
->setPluginsDir(array_merge($smarty->getPluginsDir(), [$appPlugin, $frameworkPlugin]) );
return $smarty;
}
}
SmartyConfigureProvider modify smarty object as we need..
This provider class can be changed by override binding.
class MySmartyConfigProvider implements ProviderInterface
{
/**
* @param Smarty $smarty
*
* @Inject
*/
public function __construct(Smarty $smarty)
{
$this->smarty = $smarty;
}
/**
* Return instance
*
* @return Smarty
*/
public function get()
{
// config here
return $this->smarty;
}
}
SmartyModule connects all together.
class SmartyModule extends AbstractModule
{
/**
* Configure dependency binding
*
* @return void
*/
protected function configure()
{
$this
->bind('BEAR\Sunday\Extension\TemplateEngine\TemplateEngineAdapterInterface')
->to(__NAMESPACE__ . '\SmartyAdapter')
->in(Scope::SINGLETON);
$this
->bind('Smarty')
->annotatedWith('configured')
->toProvider(__NAMESPACE__ . '\SmartyConfigProvider');
$this
->bind('Smarty')
->toProvider(__NAMESPACE__ . '\SmartyProvider')
->in(Scope::SINGLETON);
}
}
SmartyAdapter needs @nAmed annotation to have "configured" dependency.
class SmartyAdapter implements TemplateEngineAdapterInterface
{
...
/**
* Constructor
*
* Smarty $smarty
*
* @Inject
* @Named("configured")
*/
public function __construct(Smarty $smarty)
{
$this->smarty = $smarty;
}
素案でこういうのを考えてみました。
ping @tanakahisateru
古い設定ファイルが残っています。
apps/Sandbox/Module/config.php
Use global namespace to make reuse easier.
These are current public(htdoc) scripts.
オブジェクトがどんな値を保持してもシリアライズできる機能。プロパティにPDOオブジェクトやクロージャが含まれれば除去する。配列やオブジェクトは再帰で除去する。
(new Serailizer)->serialize($object);
プロパティにシリアライズ付加のものがあれば全て除去してシリアライズでエラーが出ないようにする。復元のためのシリアライズではなく、記録のためのシリアライズ。
除去ログオブジェクト
に置換?HTMLの外部ファイルの読み込みを、PHPの実行完了前に開始する
この図のように通常フレームワークの処理がすべて終わってから(ページレンダリングが完全に準備完了になってから)HTMLの出力が行われ、htmlの<head>
の中で外部のスタティックなファイル(JS/CSS)を読み込み始める。
</head>
タグまでが固定化されたものであるなら先にそれを出力すればレスポンス向上に貢献するのではないか。
/**
* @Pipleline(200)
*/
例)200のコードと</head>
までの部分的な出力を依頼するアノテーション
マニュアルの改善
アスペクトを織り込んだオブジェクトのインターフェイスを変えない機能。現状はRay.Aopを使ってアスペクトを織り込むとWeaverクラス(アスペクトを織り込んだオブジェクトを委譲実行するクラス)にオブジェクトが変更されていしまう。
同じインターフェイスを保持するクラスを自動生成してアスペクトを含んでもインターフェイスが変わらないようにする。
アスペクトを織り込んでもインターフェイスが変わらないので、インターフェイスに依存するインジェクトポイント(セッターやコンストラクター)でインジェクトが可能。
これまでもフレームワークのコンポーネントを入れ替える事が出来立たが、これが可能になれば全てのオブジェクトにアスペクトを織り込む事ができるようになる。
例えば以下のクラスにアスペクトを織り込む事を考える。
interface doInterface
{
public function doSomething($param1, $param2);
}
class Foo implements doInterface
{
public function doSomething($param1, $param2)
{
}
}
以下のような「アスペクトを織り込んだオブジェクトを保持して、実行を委譲するクラス」を自動生成する。
class Foo_AspectWeaved extends Foo implements doInterface
{
use AspectTrait;
private $weaver;
public function setWeaver($object, Weave $weaver)
{
$this->object = $object;
$this->weaver = $weaver;
}
public function doSomething($param1, $param2)
{
return $this->weaver->doSomething($param1, $param2);
}
}
自動生成はインターフェイスを保持したままメソッド実行をアスペクト織り込み済みのクラスに委譲する。プロパティアクセスはAspectTrait
をuseする事でカバーする。
trait AspectTrait
{
protected $object;
/**
* Return public property
*
* @param string $name
*
* @throws UndefinedProperty
*/
public function __get($name)
{
if (isset($this->object->$name)) {
return $this->object->$name;
}
throw new UndefinedProperty(__METHOD__ . ':' . get_class($this->object) . '::$' . $name);
}
/**
* Set public property
*
* @param string $name
* @param mixed $value
*/
public function __set($name, $value)
{
$this->object->$name = $value;
}
/**
* Return string
*
* @return string
*/
public function __toString()
{
return (string)$this->object;
}
/**
* Return offsetExists
*
* @param mixed $offset
*
* @return bool
* @throws \RuntimeException
*/
public function offsetExists($offset)
{
if (!$this->object instanceof ArrayAccess) {
throw new RuntimeException('ArrayAccess not allowed.');
}
return isset($this->object[$offset]);
}
/**
* Return offset exists
*
* @param mixed $offset
*
* @return mixed
* @throws \RuntimeException
*/
public function offsetGet($offset)
{
if (!$this->object instanceof ArrayAccess) {
throw new RuntimeException('ArrayAccess not allowed.');
}
return $this->object[$offset];
}
/**
* Set
*
* @param string $offset key
* @param mixed $value
*
* @throws RuntimeException
*/
public function offsetSet($offset, $value)
{
if (!$this->object instanceof ArrayAccess) {
throw new RuntimeException('ArrayAccess not allowed.');
}
$this->object[$offset] = $value;
}
/**
* Unset
*
* @param string $offset key
*/
public function offsetUnset($offset)
{
unset($this->object[$offset]);
}
}
apc_compile_file
した後に消去可能Now we have a 3rd application - "Skeleton"
Developer starts project with this skeleton application.
Rename apps/Skeleton/* as well as composer.json for auto loading.
[hoge@hostname public]# pwd
/tmp/bear/apps/MyApp/public
[hoge@hostname public]# php api.php get /
PHP Fatal error: Call to private method BEAR\Package\Provide\Router\MinRouter::getMethodQuery() from context '' in /tmp/bear/apps/MyApp/public/api.php on line 43
target
/**
* @param string $title
* @param string $body
*
* @Form
*/
public function onPost($title, $body)
{
before
const TITLE = 0;
const BODY = 1;
public function invoke(MethodInvocation $invocation)
{
$args = $invocation->getArguments();
if ($args[self::TITLE] === '') ...
we need to specify the the order of parameters.
after
use NamedArgsInject;
public function invoke(MethodInvocation $invocation)
{
$args = $this->namedArgs->get($invocation);
if ($args['title'] === '') ...
with use NamedArgsInject, you can use "named parameter".
If you encounter the error as shown below,
もしインストールでこのようなエラーがでたら
[Composer\Downloader\TransportException]
The "https://packages.zendframework.com/composer/Zend_Db-2.1.3.zip" file could not be downloaded (HTTP/1.1 404 Not Found)
try --prefer-source.
これで試してみて下さい。zipではなくgit cloneします。
$ curl -s https://getcomposer.org/installer | php
$ php composer.phar create-project --prefer-source --dev bear/package bear
Hope you will have no more problems with install.
We can create 'MyApp' new application as follows.
bin/new_app.php MyApp
this "composer create-project" wrapping is not only to reduce the typing, but also the script can handle more complicated creation (choose component or compatibility control) later.
Etagを用いて無変更のコンテンツに対して304を返す。正しいHTTPレスポンスを返すとともにパフォーマンスアップを計る。
class News extend AbstractObject
{
/**
* @NotModified
*/
public function onGet()
{
こういうニュースリソースがあったとして、リソースの状態変更は管理ツールで行うとする。変更したときにEtagを再生成するようにする。
php bin/new_res.php Sandbox page://self/one
New resource file path is wrong as "apps/Sandbox/Resource/PageOne.php"
開発時にリソースの周囲に出る"ハロー"(リソース境界を示す線)とツールをリソースコンテンツの内側にだしてレイアウトが崩れないようにする
php web.php read /
should return 400 Bad Request
php web.php delete /
should return 405 Method Not Allowed
While README.md tells like this,
$ php composer.phar create-project -s dev --dev bear/skeleton ./{yourAppName}
At /{yourAppName} parameter It seems "MyApp" works fine but "myApp" doesn't.
The error I've encountered today was:
[hoge@hostname public]# pwd
/tmp/bear/apps/myApp/public
[hoge@hostname public]# php api.php get /
500 Internal Server Error
x-exception-class: ["BEAR\\Package\\Provide\\Application\\Exception\\InvalidMode"]
x-exception-message: ["Invalid mode [Api], [MyApp\\Module\\ApiModule] class unavailable"]
x-exception-code-file-line: ["(0) \/tmp\/bear\/src\/BEAR\/Package\/Provide\/Application\/ApplicationFactory.php:51"]
x-exception-previous: ["-"]
x-exception-id: ["e500-7cfe3"]
x-exception-id-file: ["\/tmp\/bear\/scripts\/data\/log\/e500-7cfe3.log"]
cache-control: ["no-cache"]
date: ["Sun, 17 Feb 2013 16:24:34 GMT"]
[BODY]
Internal error occurred (e500-7cfe3)
Just my guess but it looks weird that x-exception-message uses upper camel case for application name.
BEAR\Sunday\Module\Constant\NamedModule::__construct() must be of the type array, null given, called
This error triggered when cache is on and load two page.
It seems AppModul::configure() called without constructor method does not called.
Sql map library like iBatis(JAVA) or Prado(PHP)
リソースリクエストを画面表示前ではなく、PHP終了時に行う。リソースのレイジーリクエスト。
例えばmixiの足跡機能を考えてみる。画面表示前にDB操作を行う必要はなく、画面を表示してから行えばレスポンスが向上する。
例1)
shutdownQue
に対してアタッチされたリクエストはPHP終了時に行われる
use ShtdownQueInject;
public function onGet()
{
$this->shutdownQue->attach([
$this->resource->post->uri('app://self/footprint')->request(),
$this->resource->post->uri('app://self/admin/log')->request()
]);
}
Consider faster serialization with external library.
bin/env.php ではDB接続問題ないのに、
php api.php get app://self/blog/posts するとPASSWORDが''な状態でDB接続エラーになる。
38行目の$globalsという変数は、大文字の$GLOBALSの間違いのようです。
https://github.com/koriym/BEAR.Package/blob/develop/apps/Sandbox/public/api.php
依存グラフの描画。現在のprint_oのような(あるいは進化させた)もの。
この図はGuiceのオブジェクトグラファーによるもの https://code.google.com/p/google-guice/wiki/Grapher
リソースオブジェクトのメソッド全体をプリペアードステートメントと見なして扱うアスペクトを用意してクエリーキャッシュを使いパフォーマンスのアップを計る。
/**
* @param null $id
*
* @Statement
*/
public function onGet($id = null)
{
$sql = "SELECT id, title, body, created, modified FROM {$this->table} WHERE id = :id";
$stmt = $this->db->prepare($sql);
$stmt->bindValue('id', $id);
$stmt->execute();
$this->body = $stmt->fetch(PDO::FETCH_ASSOC);
}
例えば上記メソッドなら、最初のリクエストはprepare
が必要だが次回のクエリーはそのprepareの結果を利用して'bindValue'と'execute'だけを行いbodyにセットする。
@Statementがアノテートされているメソッドに適用するアスペクトとして実装。
速度。特にn+1系、リソースリンクで繰り返し単純なSQLを発行するときに有効では?
exception 'BEAR\Resource\Exception\MethodNotAllowed' with message 'MyApp\Resource\Page\Index::onHead()
in Sakura VPS, but not in OSX local apache environment.
Router should not accept HEAD. (or onHead method check ?)
Remove requirement ini setting
apc.enable_cli - provide mock function script
xhprof.output_di - use sys_get_temp_dir
テスト・スクリプトの自動生成
If you start with 'Dev' mode the Web server,
public/web.php
$mode = 'Dev';
% php -S localhost:8088 web.php
The first request succeeds, but the second fail.
Probably 'src/Bear/Resource/Devinvoker.php' is related to this error.
It works when using the "Invoker" instead of "Devinvoker".
src/BEAR/Package/Module/Resource/DevResourceModule.php
protected function configure()
{
// DBAL debug
$this->bind('Doctrine\DBAL\Logging\SQLLogger')->to('Doctrine\DBAL\Logging\DebugStack')->in(Scope::SINGLETON);
// Common debug
//$this->bind('BEAR\Resource\InvokerInterface')->to('BEAR\Resource\DevInvoker')->in(Scope::SINGLETON);
$this->bind('BEAR\Resource\InvokerInterface')->to('BEAR\Resource\Invoker')->in(Scope::SINGLETON);
$this->install(new ProvideModule\ResourceView\DevRendererModule($this));
$this->installDevLogger();
}
英語自信ないので日本語で補足します。
'Dev'モードの時、どのページでもいいので一旦表示させたあとにリロードするとwebサーバーがsegmentation faultで落ちてしまいます。
Invorkerを使うようにすると普通に動くので、DevInvokerが関係していそう、というところまでは調べたのですがその先が追えていません。
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>@koriym $mode = 'Stub';が小文字、config/stubパスがデフォルトのSandboxスケルトンとマニュアルでずれているような気がします。
— kuma_nana (@kuma_nana) July 18, 2013
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>BEAR.Sundayのブログチュートリアルが古いみたいで指示通りにやってもスタブ使えない…ディレクトリ構成も随分変わってるみたいだしつらい…
— halt (@Halt) August 13, 2013
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>@halt あぁぁ…. ディレクトリ構成は確かに古いものと今とでは変わってますね….
— NEKOGET (@NEKOGET) August 13, 2013
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.