laruence / yaf Goto Github PK
View Code? Open in Web Editor NEWFast php framework written in c, built in php extension
Home Page: http://pecl.php.net/package/yaf
License: Other
Fast php framework written in c, built in php extension
Home Page: http://pecl.php.net/package/yaf
License: Other
我把yaf.use_namespace 设置为1以后,使用yaf_cg生成的代码中, 类名仍然是以下划线连接的
希望能开源一个实际应用Yaf的项目代码(剥除涉密部分),分享一些YAF最佳实践给大家
帮助大家把Yaf应用搭建得更健壮
Currently if I try to sub-class the Yaf_Controller_Abstract class and then have my controllers extend the sub-class I created I receive the following error:
Controller must be an instance of Yaf_Controller_Abstract
Surely this can not be a limitation as it seriously inhibits basic programming fundamentals.
Hi Laruence,
We are about to go into production with 2.2.9, and we were wondering if it is worth doing so or whether we should compile the latest code?
Also, do you know when the next release is likely to be?
Thanks!
需要在应用的各个地方,比如功能简单到只返回301/302跳转url的控制器、比如视图中要输出url渲染为页面链接……生成和路由协议匹配的url
看文档,发现好像需要调用 _.get_Path 然后手工添加余下部分(比如user params)。
通常场景下,这很直接方便,毕竟一个项目通常开始就确定了路由协议的,
但是我这里路由协议经常是随着项目变化而不同的,
手工添加余下部分在前一个项目是用querystring格式,
而后一个若是rewrite的话就代码完全无法复用……
所以请问鸟哥是否有官方的方法能生成随着路由协议不同而结果不同的url?
方法只依赖架构,举个拙例:
function createUrl(
params=array()
, action_name="."
, controller_name='.'
, action_name="."
, module_name='../parent_module_name'
) {
}
这个函数的结果随着路由协议不同而生成不同url(querystring或者rewrite形式……)。
P.S
url的显示是业务依赖的(经常不受开发人员控制,比如中小网站有个职位叫seo manager,
直接掌握任何页面的url形式,不容商量),
而代码逻辑是架构依赖(控制器、动作,这个是完全在开发人员手中,
甚至控制器、动作名可用rewrite来实现别名而摆脱URL形式对架构的染指)的,
这个createUrl的初衷将业务和架构彼此分开,并考虑到默认情况(比如默认为当前action,用“.”来标识,
控制器、模块类似……)。
../parent_module_name 这个是多层模块的情况(复杂或者繁琐,这里只是举例)下,
在子模块中返回父模块url的情况(不关心当前路由链的绝对路径的场景,类似shell的 cd .. 命令)……
当然我说的场景都是繁杂的情况,可能不符合yaf的哲学,献丑了。
Please create pre-build yaf_cg
An application for building and managing Phars. http://box-project.org/
Sources: https://github.com/kherge/Box
不好意思,又来打扰你了,有许多配置参数想写到.ini的配置文件里,想分成多个文件,请问yaf应该怎么写,如和单独读取某个配置文件。
我继承了Yaf\Controller_Abstract,重写了__get方法,发现在无任何实例属性访问时,系统仍然会自动执行一次该方法,
例如:__get($name){ echo $name; } 每次访问都会额外输出 yafAutoRender。
本想在controller里加一个便捷的访问模块的方法。
<?php
const APPLICATION_PATH = __DIR__;
$api = new Yaf_Application(APPLICATION_PATH);
$api->bootstrap()->run();
this code throws the following error..
Fatal error: Uncaught exception 'Yaf_Exception_TypeError' with message 'Expects a string or an array as parameter' in .....
This error message is some what misleading...
I'm obviously providing a string in arg#1...
The error message should say something like this...
Expects a path to application.ini file as a string or a configuration array as parameter
Is there a way to handle routes that contain a dash in it. The only solution I came up with is to do a regex rewrite but it has to be done for each action.
When we have this same controller in two modules, example:
/application
|/constrollers
| |--/Index.php
|/modules
| |/Admin
| | |/controllers
| | | |/Index.php
And in /modules/Admin/controllers/Index.php we do:
...
$this->forward('Index', 'index', 'index');
...
Then run indexAction in IndexController in Admin module but we want Index module.
My suggestion is to use namespace for controllers and models, with the name of the module. No namespace is the default module. Example
namespace Admin;
class IndexController
{
public function indexAction()
{
$model = new \Admin\UserModel();
}
}
现在有init, 但是没有对应的uninit来对每个不同的controller做类似析构的操作..
需要加么, 这个功能在大多数框架中有使用场景
您好:
请问以上两个问题如何解决
设置了一个Regex路由,girl/([\d]+)
,但是路由不到,最后都到了404. (前面两个路由都work)
public function _initRoute(\Yaf\Dispatcher $dispatcher) {
//在这里注册自己的路由协议,默认使用简单路由
$router = \Yaf\Dispatcher::getInstance()->getRouter();
$route_0 = new \Yaf\Route\Rewrite(
'*',
array(
'controller' => 'index',
'action' => 'notfound')
);
$route_1 = new \Yaf\Route\Rewrite(
'article/:id',
array(
'controller' => 'index',
'action' => 'echo')
);
$route_2 = new \Yaf\Route\Regex(
'girl/([\d]+)',
array(
'controller' => 'girl',
'action' => 'number'
),
array(
1 => 'id'
)
);
$router->addRoute('notfound', $route_0);
$router->addRoute('article', $route_1);
$router->addRoute('girl', $route_2);
}
the map parameter of Yaf_Route_Regex::__construct could be optional.
现在想自定义这么一个路由规则:
$route = new Yaf\Route\Regex(
"#^/data/([^/]+)/([^/])+#", array('controller' => ":name", 'action'=>":action"), array( 1 => "name", 2=>"action" )
);
$dispatcher->getRouter()->addRoute('data', $route);
$routes = Yaf\Dispatcher::getInstance()->getRouter()->getRoutes();
页面提示:
Error Msg:Failed opening controller script E:\Sync\Works\Yaf\portal\controllers:name.php: No such file or directory
但奇怪的是在 Nginx 下却完全正常。
我想要匹配的是:
c1.yaf.com/data/groupon/test
期待大大帮忙。
Yaf_Dispatcher::disableView()
Yaf_Dispatcher::enableView()
Yaf_Dispatcher::autoRender()
例如Yaf_Dispatcher::autoRender(true)和Yaf_Dispatcher::enableView()这两个操作有没有区别?
Hello,
It seems that we cannot forward to an action that is defined in a separate file;
My actions
class ScrapAction extends Yaf_Action_Abstract {
/* a action class shall define this method as the entry point */
public function execute() {
var_dump('EXECUTE');
}
public function testAction(){
die("ACTION TEST");
}
}
in my controller :
class IndexController extends Yaf_Controller_Abstract
{
public $actions = array(
/** now dummyAction is defined in a separate file */
"scrap" => "actions/Scrap_action.php",
);
public function indexAction(){
var_dump("ACTIONS", $this->actions);
Yaf_Dispatcher::getInstance()->disableView();
$this->forward(null, null,"scrap"); // don't work
$this->forward(null, null,"test"); // don't work
}
}
Here no forward is done
I have a Yaf Application with modules, but it is not resolving modules right, because when I try to access a module it always try to route to default module and find the controller inside it:
Here you can see the application.ini file:
[product]
;layout
application.directory = APP_PATH
application.bootstrap = APP_PATH "Bootstrap.php"
application.library = APP_PATH "../library"
application.layoutFile = 'admin_layout.phtml';
application.layoutDir = APP_PATH "layout"
application.modules="index,admin"
application.baseUri=""
application.dispatcher.defaultRoute=""
application.dispatcher.throwException=1
application.dispatcher.catchException=1
application.dispatcher.defaultModule="admin"
application.dispatcher.defaultController="admin"
application.dispatcher.defaultAction="index"
When accessing the root URL of my app I get:
Could not find controller script /home/projects/yaf_app/web/../application/controllers/Admin.php
And here the folder structure:
- application
- controllers
Error.php
Index.php
+ config
- modules
- controllers
Admin.php
+ views
+ views
And the Yaf_Request_Http before preDispatch:
class Yaf_Request_Http#4 (11) {
public $module =>
string(5) "Admin"
public $controller =>
string(5) "Admin"
public $action =>
string(5) "index"
public $method =>
string(3) "GET"
protected $params =>
array(0) {
}
protected $language =>
NULL
protected $_exception =>
NULL
protected $_base_uri =>
string(0) ""
protected $uri =>
string(1) "/"
protected $dispatched =>
bool(false)
protected $routed =>
bool(true)
}
Maybe I am doing something wrong but it worked for me in another project.
use Yaf_Load import one inlcude sql_autoload_register
file
will have one error: Failed opening script /Users/sampeng/Work/user/ExecFuture.php.
but,this file is include by sql_autoload_register,I take the place of require_once ,this error solve
I'm creating stubs for Yaf running with yaf.use_namespace set to 1. Static is a reserved keyword and therefore class cannot be initialized properly.
Issue resolved.
I was thinking for a feature in controller class, about exceptions.
Yaf can catch exceptions, by setting catchException to true in application.ini, and forwards to the Error controller.
It would be nice to give the developer the chance to rescue this exception through a controller method, without turning off the usefull in most cases catchException option.
For example, an apllication may not throws only error exceptions. There are 404 not found exceptions or 401 Unauthorized exceptions or 403 Forbidden exceptions.
A method in controller rescueFromException(Exception $e) would be usefull.
By default would forward to ErrorController, if catchException is on, but developer could overload it and make some checks and forward other controllers, according to exceptions.
// This method would be triggered on exceptions
public function rescueFromException(Exception $e)
{
if (get_class($e) == 'AccessDenied') {
$this->forward('index', 'application', 'accessDenied');
// forward to accessDeniedAction and renders a different page than the error page.
header('HTTP/1.0 401 Unauthorized');
return false;
} else {
parent::rescueFromException($e);
// forward to ErrorController
}
}
I found out there's no docs for "Yaf_Response_Abstract::setHeader"
Would anyone please tell me how to set a response heaser
and I tried $response->setHeader('Content-Type: application/json');
it wont work;
Yaf_Loader
seems to be not able to resolve classes which are end with Controller
.
It tries to look up /MyBase/.php
for MyBase_Controller
in controllers
directory.
I expect that it tries to look up /MyBase/Controller.php
in library
directory.
This is the test code:
<?php
$app = new Yaf_Application([
"application" => [
"directory" => __DIR__,
],
]);
$loader = Yaf_Loader::getInstance(__DIR__);
$loader->registerLocalNameSpace(['MyBase', 'Foo']);
$loader->autoload('MyBase_Controller'); // NG
$loader->autoload('Foo_Bar_Controller'); // NG
$loader->autoload('Foo\\Bar\\Controller'); // NG
$loader->autoload('MyBase_Controller2'); // OK
And that result is:
$ php test.php
Warning: Yaf_Loader::autoload(): Could not find script /private/tmp/controllers/MyBase/.php in /private/tmp/test.php on line 11
Call Stack:
0.0002 228864 1. {main}() /private/tmp/test.php:0
0.0005 233728 2. Yaf_Loader->autoload() /private/tmp/test.php:11
Warning: Yaf_Loader::autoload(): Could not find script /private/tmp/controllers/Foo/Bar/.php in /private/tmp/test.php on line 12
Call Stack:
0.0002 228864 1. {main}() /private/tmp/test.php:0
0.0029 233776 2. Yaf_Loader->autoload() /private/tmp/test.php:12
Warning: Yaf_Loader::autoload(): Could not find script /private/tmp/controllers/Foo/Bar/.php in /private/tmp/test.php on line 13
Call Stack:
0.0002 228864 1. {main}() /private/tmp/test.php:0
0.0033 233776 2. Yaf_Loader->autoload() /private/tmp/test.php:13
Warning: Yaf_Loader::autoload(): Could not find script /private/tmp/MyBase/Controller2.php in /private/tmp/test.php on line 14
Call Stack:
0.0002 228864 1. {main}() /private/tmp/test.php:0
0.0038 233776 2. Yaf_Loader->autoload() /private/tmp/test.php:14
Thank you.
yaf源码中,yaf_router.h 第27行
表示路由器下的所有路由协议,命名为_ROUTERS 易误解为所有路由器,建议去掉R
好吧,我是不是没事找抽...
Following yaf_response methods are missing implementation in yaf_response_http:
/** {{{ proto public Yaf_Response_Abstract::setHeader($name, $value, $replace = 0)
*/
PHP_METHOD(yaf_response, setHeader) {
RETURN_FALSE;
}
/* }}} */
/** {{{ proto protected Yaf_Response_Abstract::setAllHeaders(void)
*/
PHP_METHOD(yaf_response, setAllHeaders) {
RETURN_FALSE;
}
/* }}} */
/** {{{ proto public Yaf_Response_Abstract::getHeader(void)
*/
PHP_METHOD(yaf_response, getHeader) {
RETURN_NULL();
}
/* }}} */
/** {{{ proto public Yaf_Response_Abstract::clearHeaders(void)
*/
PHP_METHOD(yaf_response, clearHeaders) {
RETURN_FALSE;
}
请问,我希望在访问某个controller时未找到方法时可以去__call,如何处理?谢谢!
鸟哥. 好.
我想在PHP5.5下使用 Trait, Yaf 能自动载入 包含Trait 的文件么? 就像 Model,或者 Lib 一样?
如果能, 请问怎么设置
如果不能, 请问是否会增加这样特性?
谢谢.
Hello,
I cannot just figure out how to make tests using PHPUnit and Yaf while having to test also some Yaf plugins. The only way I was able to achieve that is to prepare a subclass of Yaf_Request and inject it into the dispatcher by setRequest() done in setUp method for TestCase.
Is there any better way to achieve that, by for e.g. preparing cookies and pass them to Yaf_Request object (something like setCookies)?
abstract class Yaf_Action_Abstract has an abstract method named execute
, abstract class Yaf_Config_Abstract has the same problem.
I also create a test file:
abstract class Test
{
abstract function abc() {}
}
the output is:
Fatal error: Abstract function Test::abc() cannot contain body in ... on line 5
remove the abstract modifier solved the problem.
So... is this an issue?
I noticed Yaf_Dispatcher::setErrorHandler
can't receive closure as a callback.
This code works:
<?php
function myErrorHandler($errorCode, $errorMessage, $file, $line)
{
throw new ErrorException($errorMessage, 0, $errorCode, $file, $line);
}
class Bootstrap extends Yaf_Bootstrap_Abstract
{
protected function _initErrorHandler(Yaf_Dispatcher $dispatcher)
{
$dispatcher->setErrorHandler("myErrorHandler");
}
}
However, this code doesn't work
<?php
class Bootstrap extends Yaf_Bootstrap_Abstract
{
protected function _initErrorHandler(Yaf_Dispatcher $dispatcher)
{
$dispatcher->setErrorHandler(function($errorCode, $errorMessage, $file, $line) {
throw new ErrorException($errorMessage, 0, $errorCode, $file, $line);
});
}
}
$ php -v
PHP 5.4.5 (cli) (built: Aug 12 2012 18:49:16)
Copyright (c) 1997-2012 The PHP Group
Zend Engine v2.4.0, Copyright (c) 1998-2012 Zend Technologies
with Xdebug v2.2.0, Copyright (c) 2002-2012, by Derick Rethans
My yaf version is 2.1.18.
$ php -i | grep yaf
yaf
yaf support => enabled
Supports => http://pecl.php.net/package/yaf
yaf.action_prefer => Off => Off
yaf.cache_config => Off => Off
yaf.environ => devel => devel
yaf.forward_limit => 5 => 5
yaf.library => no value => no value
yaf.lowcase_path => Off => Off
yaf.name_separator => no value => no value
yaf.name_suffix => On => On
yaf.st_compatible => Off => Off
yaf.use_namespace => Off => Off
yaf.use_spl_autoload => Off => Off
As the manual said:
You cannot use any of the following words as constants, class names, function or method names.
I also create a test file:
class Test {
function eval() {}
}
$test = new Test();
$test->eval();
the output is:
Parse error: syntax error, unexpected 'eval' (T_EVAL), expecting identifier (T_STRING) in ... on line 4
So is it an issue?
你好鸟哥:
我在用YAF的时候使用forward/转跳的时候原Action的模板和新Action的模板都会被输出,断点测试了下render被调用2次。
不知道是我构成了Yaf\View_Interface 改用smarty的原因了还是原本就有这个问题。
我用的是2.3.2版本
我现在是默认的Index模块在application文件夹下边,其它模块在application下的modules下边,但是这样我访问其它模块的时候,需要指定模块/controller/action,如果没有指定到action级别,就会访问到默认的Index模块,我想是不是能把index模块也弄到modules里去?
这样就可以不用加默认的controller/action了
在服务器dmesg中查到大量报错如下:
[8465402.373110] php5-fpm[2329]: segfault at 10181592f ip 00007f0f0f6709c6 sp 00007fff16283638 error 4 in libc-2.15.so[7f0f0f527000+1b5000]
[8465404.455885] php5-fpm[2367]: segfault at 2ca1000 ip 00007fe3d2e638c4 sp 00007fff96861268 error 6 in libc-2.15.so[7fe3d2d1a000+1b5000]
[8465405.006887] php5-fpm[2083]: segfault at 101870f87 ip 00007f1765c5e9c6 sp 00007fffd6a33498 error 4 in libc-2.15.so[7f1765b15000+1b5000]
[8465409.078165] php5-fpm[2423]: segfault at 5823000 ip 00007f98690618d3 sp 00007fff8191eb68 error 6 in libc-2.15.so[7f9868f18000+1b5000]
[8465420.685318] php5-fpm[2365]: segfault at 1027d5a7f ip 00007fe3d2e639c6 sp 00007fff96861268 error 4 in libc-2.15.so[7fe3d2d1a000+1b5000]
[8465425.057961] php5-fpm[2501]: segfault at 101a61a8f ip 00007f1765c5e9c6 sp 00007fffd6a33498 error 4 in libc-2.15.so[7f1765b15000+1b5000]
[8465425.703124] php5-fpm[2402]: segfault at 1dbe000 ip 00007f98690618d8 sp 00007fff8191eb68 error 6 in libc-2.15.so[7f9868f18000+1b5000]
[8465445.054118] php5-fpm[2050]: segfault at 585b000 ip 00007f98690618d8 sp 00007fff8191eb68 error 6 in libc-2.15.so[7f9868f18000+1b5000]
[8465470.522951] php5-fpm[2328]: segfault at 1024d6fff ip 00007fe3d2e639c6 sp 00007fff96861268 error 4 in libc-2.15.so[7fe3d2d1a000+1b5000]
[8465486.467350] php5-fpm[1897]: segfault at 1017a896f ip 00007f0f0f6709c6 sp 00007fff16283638 error 4 in libc-2.15.so[7f0f0f527000+1b5000]
获取core后跟踪到以下信息:
warning: Can't read pathname for load map: Input/output error.
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Core was generated by `php-fpm: pool www-9006 '.
Program terminated with signal 11, Segmentation fault.
#0 0x00007f44602fe8dd in ?? () from /lib/x86_64-linux-gnu/libc.so.6
(gdb) bt
#0 0x00007f44602fe8dd in ?? () from /lib/x86_64-linux-gnu/libc.so.6
#1 0x000000000067c2e6 in _estrndup ()
#2 0x00007f4455900235 in yaf_application_parse_option (options=) at /tmp/pear/temp/yaf/yaf_application.c:143
#3 zim_yaf_application___construct (ht=, return_value=0x1f3e930, return_value_ptr=, this_ptr=0x1f3b578, return_value_used=)
at /tmp/pear/temp/yaf/yaf_application.c:358
#4 0x000000000070f05d in ?? ()
#5 0x00000000006bfbcb in execute ()
#6 0x000000000069b130 in zend_execute_scripts ()
#7 0x00000000006477a3 in php_execute_script ()
#8 0x000000000042b895 in ?? ()
#9 0x00007f44601d676d in __libc_start_main () from /lib/x86_64-linux-gnu/libc.so.6
#10 0x000000000042c0f5 in _start ()
我自己本地没重现到这个Segmentation fault,不知道是什么原因,求助 =。=
yaf版本是 2.2.9
At least missing files in official package:
Please also fix URL to source from pecl web site.
I was just trying to implement a custom view, which didn't work out that well :)
I used Reflection to create the stub of the \Yaf\View_Interface (https://github.com/theDisco/yaf-playground/blob/master/stub/yaf/View_Interface.php). I've then implemented the interface and set the view in the bootstrap by calling \Yaf\Dispatcher::setView. When I request the page in the browser the response is empty. It also seems that any of the methods in my custom view are called.
Any idea what am I doing wrong? Is it possible to implement custom views at the moment at all? I've noticed that \Yaf\Controller_Abstract is trying to determine the path independently from the view. I still get no errors/exceptions about the path not found.
yaf版本2.2.9
$conf = array(
'application'=> array(
'directory'=> APP_PATH.'/application/',
'modules' => 'Index,Test',
),
);
$app = new Yaf\Application($conf);
var_dump($app->getModules());
结果输出还是array(1) { [0]=> string(5) "Index" }
我发现php.net上的文档不是最新,我在使用Request::getParam不起作用,然后发现 Request::getQurey可以但是文档没有,是不是还有个Request::getPost。
因为我不会c语言,想知道如何查看yaf框架类的每个方法。
path/to/php yaf_cg app_name app_path
报$app_path变量未找到
修改25行
$app_name = $argv[2];
为
$app_path = $argv[2] . $app_name;
#!/bin/env php
<?php
/**
* @name conf.php
* @desc odp-cg的配置文件
* @author Wei He([email protected])
* @modifier Laruence([email protected])
*/
if ($argc < 2) {
die(<<<USAGE
Yaf Code Generetor Version 1.0.0
Usage:
{$argv[0]} ApplicationName [ApplicationPath]
USAGE
);
}
$app_name = $argv[1];
if (empty($argv[2])) {
$app_path = dirname(__FILE__) . "/output/{$app_name}";
}else{
//$app_name = $argv[2]; //here is a bug
$app_path = $argv[2] . "/{$app_name}";
}
备忘
若用正则路由的话,规则有点复杂了?
可能我没找到合适的方法,但是我用getQuery拿不到数据。
谢谢~
Is it here the right place to ask a question?
The forum is in CN. Feel free to close this issue if you like.
I'm looking at Yaf and was wondering how I would react to different responses for the same action. The framework I'm using now (agavi) we have those output_types
that can be something like XML, JSON, HTML. That is, that your response will look like. What kind of data they will delivery. You can determine what output type by many methods: request headers, URL regex (product/1/json, product/1.xml), etc.
The best way to do that IMO is using the request headers. For example, to set the output_type for JSON, test _SERVER[HTTP_ACCEPT] for "application/json", HTML if it's "text/html", XML if it's "application/xhtml+xml", and so on.
Depending on the "output" set for the response, the corresponding method in the view will be called: i.e: view::executeJon, view:executeXml.
The concept of output types are really powerful, because depending on the output you'll have different response headers and, mainly, data to show (the data needed to show a page in HTML is different than the data you need to show a response for your REST API).
So, my question is if there is anyway to create a plugin that does that so I don't need to set headers, test for request headers to define the output type in every controller/action.
Thanks.
PHP Fatal error: Uncaught exception 'Yaf_Exception_LoadFailed_Controller' with message 'Failed opening controller script XXXXXXX/application/controllers/Favicon.ico.php: No such file or directory' in ...
请问如果处理站点的favicon呢? 在哪里配置favicon的位置?谢谢。
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.