每当我尝试处理看起来像controller/foo.xtn
的路线时,Yii就会抱怨Unable to determine the path info of the current request.
。我想通过将xtn
转换为操作参数(即调用actionFoo($xtn)
)来处理这些路线,但也允许controller/foo?type=xtn
。我的计划是编写一个UrlRule来定义这种行为,但是我如何解决路径信息解析失败?
我正在使用enablePrettyUrl
,并希望enableStrictParsing
但是现在我无需处理它。
编辑:什么有效,什么无效
controller/foo/abc?type=xtn ---> actionFoo('abc', 'xtn') # works
controller/foo/abc/xtn ---> actionFoo('abc', 'xtn') # works
controller/foo/abc.xtn ---> actionFoo('abc', 'xtn') # doesn't work
getPathInfo()
尝试解析controller/foo/abc.xtn
时会抛出此错误,因此网络服务器会将其路由到Yii。
路由配置(暂时使用PHP内部网络服务器):
<?php
// www/routing.php
if (preg_match('/\.(?:png|jpg|jpeg|gif)$/', $_SERVER["REQUEST_URI"])) {
return false;
} else {
include __DIR__ . '/../web/index.php';
}
使用上面的配置,我可以看到PHP服务器设置了Yii正在读取的REQUEST_URI变量。
'REQUEST_URI' => '/controller/foo/abc.xtn?app=4'
所以我不相信这是一个网络服务器问题。这是$ _SERVER数组中唯一的重要区别:
# fails in getPathInfo()
'REQUEST_URI' => '/feeds/strings/en.json?app=4',
'SCRIPT_NAME' => '/feeds/strings/en.json',
'SCRIPT_FILENAME' => '/Users/darvids0n/NetBeansProjects/php-web-services/web/www/routing.php',
'PHP_SELF' => '/feeds/strings/en.json',
# works
'REQUEST_URI' => '/feeds/strings/en?app=4',
'SCRIPT_NAME' => '/index.php',
'SCRIPT_FILENAME' => '/Users/darvids0n/NetBeansProjects/php-web-services/web/index.php',
'PATH_INFO' => '/feeds/strings/en',
'PHP_SELF' => '/index.php/feeds/strings/en',
但是,如果您阅读Yii的source code,您会发现缺少PATH_INFO实际上并未考虑到未能确定路径信息&#39;。
答案 0 :(得分:2)
未知路径应该以404结尾。尝试重定向它可能会很棘手,你必须小心不要陷入循环。
您可以在列表中添加最后一条规则,即“最后的”路径,例如
'<controller>/<action>' => '<controller>/<action>',
任何控制器和操作都可以在这里工作。
对于文件扩展名,您可以为规则使用后缀参数。
[
'pattern' => 'posts',
'route' => 'post/index',
'suffix' => '.json',
],
如果要将扩展名传递给操作,我会坚持使用一个参数名称:
'controller/foo/<type:\w+>' => 'controller/foo'
所以你需要采取以下行动:
public function actionFoo($type)
答案 1 :(得分:0)
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button storeBTN = (Button) findViewById(R.id.button);
storeBTN.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v) {
EditText et = (EditText) findViewById(R.id.editText);
int i = Integer.parseInt(et.getText().toString());
store(i);
}
});
Button retrieveBTN = (Button) findViewById(R.id.button2);
retrieveBTN.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v) {
retrieve();
}
});
}
public void store(int newHighScore){
Log.d("Meeeeee", "store: "+newHighScore);
setContentView(R.layout.activity_main);
SharedPreferences sharedPref = this.getPreferences(this.MODE_APPEND);
SharedPreferences.Editor editor = sharedPref.edit();
editor.putInt(getString(R.string.saved_high_score), newHighScore);
boolean b = editor.commit();
Log.d("Meeee", "store: commited? "+b);
retrieve();
return;
}
public void retrieve(){
SharedPreferences sharedPref = this.getPreferences(this.MODE_APPEND);
int defaultValue = getResources().getInteger(R.integer.saved_high_score_default);
long highScore = sharedPref.getInt(getString(R.string.saved_high_score), defaultValue);
Log.d("meeee", "retrieve: "+highScore+" in mode: "+this.MODE_APPEND);
TextView scoreTV = (TextView) findViewById(R.id.textView);
scoreTV.setText(highScore+"");
return;
}
}