Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

how to create urls in yaf ? #41

Closed
openalmeida opened this issue May 31, 2013 · 15 comments
Closed

how to create urls in yaf ? #41

openalmeida opened this issue May 31, 2013 · 15 comments

Comments

@openalmeida
Copy link

需要在应用的各个地方,比如功能简单到只返回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的哲学,献丑了。

@rottekruid
Copy link

(edit) Sorry the formatting was messed up. Will post a new response.

@rottekruid
Copy link

Hello,

My solution is quick and is not perfect and not very elegant, but it might be a
starting point.

If you have something better, please reply with your better solution :)

Maybe we should start a YAF code-repository for commonly-needed functions?

First, define constant BASE_URL (or similar):

define('BASE_URL', 'http://www.example.com');

Secondly, extend the controller. I like to have a "base" controller for every
application:

/**
    * @name BaseController
    * @desc A base controller for the application
    * @see http://www.php.net/manual/en/class.yaf-controller-abstract.php
    */

class BaseController extends Yaf_Controller_Abstract {
        // ...
}

Thirdly, add method to the BaseController class:

/**
* URL generating helper intended to generating valid internal hyperlinks.
* Important: It requires that a constant named BASE_URL be defined.
*
* @param string $actionName Optional action name (defaults to current action)
* @param string $controllerName Optional controller name (defaults to current controller)
* @param string $moduleName Optional module name (defaults to current module)
* @param array $params Optional controller parameters
* @param array $getParams Optional query parameters
* @param string $target Optional target
* @return string The generated URL
*/

public function url($actionName = NULL, $controllerName = NULL, $moduleName = NULL, array $params = array(), array $getParams = array(), $target = NULL) {

    // Build URL using parts

    $urlParts = array();

    $urlParts[] = BASE_URL;

    if ($moduleName === NULL) $moduleName = $this->getRequest()->getModuleName();
    if ($controllerName === NULL) $controllerName = $this->getRequest()->getControllerName();
    if ($actionName === NULL) $actionName = $this->getRequest()->getActionName();

    $moduleName = strtolower($moduleName);
    $controllerName = strtolower($controllerName);
    $actionName = strtolower($actionName);

    // Get default module, controller and action names

    $Application = Yaf_Application::app();
    $Config = $Application->getConfig();

    $Application->getConfig()->application->dispatcher->defaultModule ? $defaultModule = $Application->getConfig()->application->dispatcher->defaultModule : $defaultModule = 'Index';
    $Application->getConfig()->application->dispatcher->defaultController ? $defaultController = $Application->getConfig()->application->dispatcher->defaultController : $defaultController = 'Index';
    $Application->getConfig()->application->dispatcher->defaultAction ? $defaultAction = $Application->getConfig()->application->dispatcher->defaultAction : $defaultAction = 'index';

    $defaultModule = strtolower($defaultModule);
    $defaultController = strtolower($defaultController);
    $defaultAction = strtolower($defaultAction);

    // Assign module name

    if ($moduleName != $defaultModule) {
        $urlParts[] = strtolower(trim($moduleName, '/')); // To validate a module, inspect its presence in $modules = $Application->getModules();
    }

    // Assign controller name

    if ($actionName != $defaultAction || $controllerName != $defaultController || $moduleName != $defaultModule) {
        $urlParts[] = strtolower(trim($controllerName, '/'));
    }

    // Assign action name

    if ($actionName != $defaultAction) {
        $urlParts[] = strtolower(trim($actionName, '/'));
    }

    // Assign parameters (assumes url parameter pairing)

    foreach ($params as $k => $v) {
        if ($v !== NULL) {
            $urlParts[] = $k;
            $urlParts[] = $v;
        }
    }

    // Assign get parameters

    $getParamsStr = '';
    foreach ($getParams as $k => $v) {
        if (!$getParamsStr) {
            $getParamsStr = '?';
        } else {
            $getParamsStr .= '&';
        }
        $getParamsStr .= rawurlencode($k) . '='. rawurlencode($v);
    }
    if ($getParamsStr) {
        $urlParts[] = $getParamsStr;
    }

    // Build the URL

    $url = implode('/', $urlParts);

    // Assign # target

    if ($target !== NULL) {
        $urlParts = explode('#', $url);
        $url = array_shift($urlParts) . '#' . rawurlencode((string) $target);
    }

    return $url;

}

Assign the controller to the view, if you want to, something like this in your
action:

$this->getView()->_controller = $this;

The it's quite simple to generate internal application URL's in the view:

<a href="<?=$_controller->url('myaction', NULL, NULL, array(),
$_GET)?>">Some link</a>
<a href="<?=$_controller->url('myaction')?>">Some link</a>
<a href="<?=$_controller->url('myaction', 'othercontroller')?>">Some link</a>

Hope it provides some guideline?

@rottekruid
Copy link

Also, a nice feature of YAF is to prefer action names when interpreting URL's

In your .htaccess, add:

# If there is only one part in PATH_INFO, should it consider as a controller
# or action. If action_prefer is configured On, it will be considered as a
# Action name.
php_value yaf.action_prefer Off

@openalmeida
Copy link
Author

Whats a quickly reply!
Thanks very much.

Yes, url generating helper is really want i've said/want,
actually that all of these:

Yaf_Route_Static
Yaf_Route_Simple
Yaf_Route_Supervar
Yaf_Route_Map
Yaf_Route_Rewrite
Yaf_Route_Regex

or more customed Yaf_Route_* classes need it to be suit.
but, url generating helper point a new way for me.

Thanks again. Thanks very much. Especially for your quickly reply.

@ghost
Copy link

ghost commented Jul 15, 2014

If your problem was resolved, please leave this ticket closed.

@zxcvdavid
Copy link
Contributor

有的..assemble,可以通过路由给出url, 文档目前不全..

@zxcvdavid
Copy link
Contributor

可以先看下 47e528e 中的测试文件

@laruence
Copy link
Owner

@zxcvdavid 你也知道文档不全? 文档不全你还在不去赶紧.......

@wenjun1055
Copy link
Contributor

至少半年了吧。。。。。。。。。。。。。

@ghost
Copy link

ghost commented Jul 15, 2014

是不是成立个Ya Foundation,专事项目开发,文档?现在太松散了,没有组织,没有纪律。

@ghost
Copy link

ghost commented Jul 15, 2014

我说不定可以贡献一点点力量。有一定的空余时间。

@zxcvdavid
Copy link
Contributor

@netroby 欢迎贡献

@zxcvdavid
Copy link
Contributor

文档周五已经提交,等 @laruence 发布到php.net就可以看到了

@openalmeida
Copy link
Author

Ok, lets end.

@shyandsy
Copy link
Contributor

@zxcvdavid 所以,到底如何在controller中使用assemble生成url啊

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants