/控制器/方法/參數1/參數2/參數3 ,參數可否傳遞物件進去
uri 透過 router 會被解為/控制器/方法/參數1/參數2/參數3
假如今天我的 my_method 方法 為下
function my_method( $obj ){
$title = $obj->title;
$subject = $obj->subject ;
}
這邊可以以物件當參數帶入嗎?
因為我看了好幾個範例都是以一個字串或是數字帶入
平常在瀏覽器也無法這樣打一個物件進去做連結
但好像帶入物件,可以使 my_method 更有彈性
就不受限它有多少參數了
還是有類似的做法嗎?
一起討論吧 URL 如何传递对象?你怎么构造这样的 URL?
URL 就是一个纯字符的东西,让他传递对象,不太可能。。。 回复 2# Hex
對阿~ 我看 URL 的外部參數都是給個編號或是字串的
像是 /blog/article/1
或是 /blog/new/all
好像只有在 php 內部參數才能丟物件
例如視圖中 :
$this->load->view('blog',$data); 是呀,URL 只能传递简单的数据,你看见过那个网站的 URL 传递对象?
不过可以传递序列化后的对象,然后在 PHP 中反序列化一下。 如果你希望后面的参数有弹性,也就是说可能有多种参数组合,那么可以考虑以下两种方式实现:
1. 给参数设置默认值:
function my_method(arg1, arg2 = 0, arg3 = '', arg4 = 'ok') {}
这样你在构造URL的时候就可以用:
/controller/method/arg1
/controller/method/arg1/arg2
/controller/method/arg1/arg2/arg3
.....
2.第二种方式是用func_get_args让PHP在runtime的时候动态获取它的参数:
<?php
function foo()
{
$numargs = func_num_args();
echo "Number of arguments: $numargs<br />\n";
if ($numargs >= 2) {
echo "Second argument is: " . func_get_arg(1) . "<br />\n";
}
$arg_list = func_get_args();
for ($i = 0; $i < $numargs; $i++) {
echo "Argument $i is: " . $arg_list[$i] . "<br />\n";
}
}
foo(1, 2, 3);
?>
回复 5# saturn
function my_method(arg1, arg2 = 0, arg3 = '', arg4 = 'ok') {}
/controller/method/arg1
/controller/method/arg1/arg2
/controller/method/arg1/arg2/arg3
如果只想傳 arg2 跟 arg3
URL 變成
/controller/method//arg2/arg3
arg1直接空下來這樣嗎?
---------------------------------------------------------------------------
我覺得第二種方式 func_get_args 很不錯,可以不限制參數
my_method 依照參數有多少個去作邏輯判斷,再去分別處裡
因為 php 現在好像不可以讓他自己去抓要用哪個 function
my_method ( arg1 ){}
my_method ( arg1 , arg2 ){}
my_method ( arg1 , arg2 , arg3 ){} url 中间不能空着吧,我觉得。 回复 6# minigogo701125
两个segment之间是不能为空的。但你的这个描述让我想起了一种解决方案,那就是用CI中的路由来完成(下面的代码来自我写的部落格程式stblog),比如:
//注意路由的顺序
$route['archives/(\d{4})'] = 'home/archives/$1/0/0/p1';
$route['archives/(\d{4})/(\d{2})'] = 'home/archives/$1/$2/0/p1';
$route['archives/(\d{4})/(\d{2})/(\d{2})'] = 'home/archives/$1/$2/$3/p1';
$route['archives/(\d{4})/p(+)'] = 'home/archives/$1/0/0/$2';
$route['archives/(\d{4})/(\d{2})/p(+)'] = 'home/archives/$1/$2/0/$3';
$route['archives/(\d{4})/(\d{2})/(\d{2})/p(+)'] = 'home/archives/$1/$2/$3/$4';
上面的router规则可以在源代码的config/routes.php中找到。它所做的功能就是将URL传递过来的参数做简单的分发(dispatch),将值传递到合适的method当中去。也就是说,method的初始值可以在route中完成(代码段中的右边部分,0就是我们的初始值,它并不出现在url中)。这样应该可以完美解决你的这个问题。
你后面说的是类似Java和.NET那种Strong object-oriented 语言的overloading,在PHP中是不支持这种overload的。但可以通过我说的那种func_get_args来模拟,比如:
function test() {
$args = function_get_args();
swtich (count($args)) {
case 1:
// one argument passed
break;
case 2:
// two arguments passed
break;
default:
// illegal numer of arguments
break;
}
}
BTW:PHP 5有一种特性也叫做overload,但是原理和实现与Java中的overload不通,具体可以看看PHP Manual。
由于这个论坛使用的是简体中文,所以台湾的朋友看起来可能不习惯。受苦了:)。建议hex增加个简体繁体转换插件(不知道Discuz是否提供,就是JS的那种)。 回复 8# saturn
router.php 我需要時間慢慢體會了
因為我的功力還不足
不過好像有那麼一點感覺了
我不清楚我會不會遇到這樣傳遞參數的問題
只是突然好奇想到,來討論看看
這些討論很受用
到時候有遇到這樣的問題就可以用這幾個方式去應用
現在很多台灣人平常看電影的字幕也都是簡體中文
可能有些名詞用的字不同,但都可以體會到大概是什麼意思 我觉得楼主的问题有一直可以解决的办法,我的个人看法是可以通常传递类名的形式,然后在控制器中实例化类
function my_method( $object ){
$obj= new $object;
$title = $obj->title;
$subject = $obj->subject ;
}
然后还得结合php5的类的自动加载功能,参考一下ci第三方类库Datamapper的实现方式
//DataMapper::autoload静态方法首先在APPPATH的model文章就寻找类,如果没有找到就
//在子文件夹中递归搜索
spl_autoload_register('DataMapper::autoload');
static function autoload($class)
{
// Don't attempt to autoload CI_ or MY_ prefixed classes
if (in_array(substr($class, 0, 3), array('CI_', 'MY_')))
{
return;
}
// Prepare class
$class = strtolower($class);
// Prepare path
$path = APPPATH . 'models';
// Prepare file
$file = $path . '/' . $class . EXT;
// Check if file exists, require_once if it does
if (file_exists($file))
{
require_once($file);
}
else
{
// Do a recursive search of the path for the class
DataMapper::recursive_require_once($class, $path);
}
}
// --------------------------------------------------------------------
/**
* Recursive Require Once
*
* Recursively searches the path for the class, require_once if found.
*
* @access public
* @param string
* @param string
* @return void
*/
static function recursive_require_once($class, $path)
{
if ($handle = opendir($path))
{
while (FALSE !== ($dir = readdir($handle)))
{
// If dir does not contain a dot
if (strpos($dir, '.') === FALSE)
{
// Prepare recursive path
$recursive_path = $path . '/' . $dir;
// Prepare file
$file = $recursive_path . '/' . $class . EXT;
// Check if file exists, require_once if it does
if (file_exists($file))
{
require_once($file);
break;
}
else if (is_dir($recursive_path))
{
// Do a recursive search of the path for the class
DataMapper::recursive_require_once($class, $recursive_path);
}
}
}
closedir($handle);
}
}
页:
[1]
2