本文將記錄我在Phalcon開發(fā)過程中遇到的問題,以及如何如何解決。
本文首發(fā)在我的博客,我更新之后會(huì)更新過來;如果想查看最新的,可以到我的博客:Phalcon填坑手冊(cè):開發(fā)中會(huì)遇到的問題和解決方案(不斷更新)
1. 正確地在控制器中獲取參數(shù)一般情況下,GET/POST請(qǐng)求獲取參數(shù):
$this->request->get(參數(shù)名); $this->request->getPost("參數(shù)名")
路由模式下route獲取參數(shù)要用dispatcher->getParam();
route下定義好了參數(shù)名稱可以直接通過參數(shù)名稱來獲?。?/p>
this->dispatcher->getParam("參數(shù)名");
route沒有定義好名稱,只是規(guī)則中寫了:params做匹配,可以在控制器中按順序來獲?。?/p>
class NewsController extends Controller { public function showAction($id, $testParam) { echo $id, "|" , $testParam; } }2. 為 url 定制路由
默認(rèn)自動(dòng)解析/:controller/:action/:params模式:
在實(shí)例化時(shí),不加false參數(shù):
$router = new Router();
url將會(huì)自動(dòng)進(jìn)行/:controller/:action/:params參數(shù)的解析, 比如https://www.goozp.com/login將會(huì)解析成Login controller下的默認(rèn)action。
當(dāng)使用路由時(shí),保留默認(rèn)解析模式有時(shí)候會(huì)導(dǎo)致解析混亂,比較建議采用完全自定義路由模式。
完全自定義路由,在new時(shí)加上false:
$router = new Router(false);
不自動(dòng)解析/:controller/:action/:params這些規(guī)則, 具體的路由匹配規(guī)則自己來編寫,例如:
$router->add("/login", [ "module" => "admin", "controller" => "login", "action" => "index", ] )->setName("login");
這樣不會(huì)因?yàn)樽詣?dòng)解析而導(dǎo)致url混亂,但是所有url都要自己來定制路由規(guī)則。
3. flash提示重寫后輸出不正確 (未解決)重寫后輸出的html標(biāo)簽是字符串,外面帶""
4. Config 中 baseURI 的正確設(shè)置因?yàn)橛蠥pache+.htaccess文件重寫規(guī)則 或者 nginx配置到public/index.php的重寫規(guī)則,我們不需要項(xiàng)目中的url帶有/publc/index.php。
但是默認(rèn)是指到了/public/index.php中(比如$_SERVER["PHP_SELF"]獲取從根目錄到當(dāng)前頁(yè)面本身的路徑); 所以,如果有Apache重寫規(guī)則或者nginx配置到public/index.php的重寫配置,我們需要把url設(shè)置為不帶public/index.php的,于是就有了官方的這個(gè)設(shè)置:
使用 $_SERVER["PHP_SELF"],并且正則去除/public/index.php
"baseUri" => preg_replace("/public([/])index.php$/", "", $_SERVER["PHP_SELF"]),
這是動(dòng)態(tài)寫法,這種寫法的問題在于 $_SERVER["PHP_SELF"] 的不確定性,返回的值將根據(jù) Apache 或 nginx 配置的 root,是否配置host或者域名,$_SERVER["PHP_SELF"]會(huì)有不同的返回值。這樣的話上面寫法前面的正則并不是全部兼容的,所以這樣寫調(diào)試起來就稍麻煩。
簡(jiǎn)單一點(diǎn),用靜態(tài)寫法:
設(shè)置host或者配置域名
"baseUri" => "/",
如果是想在localhost下直接打開,則需要加上項(xiàng)目外層目錄名,例如:
"baseUri" => "/zphal/",
這樣的話,我們?cè)诙xurl服務(wù)的時(shí)候只需要把這個(gè)定義的配置傳進(jìn)去:
$di->setShared("url", function () { $config = $this->getConfig(); $url = new UrlResolver(); $url->setBaseUri($config->application->baseUri); // baseUri return $url; });
以上寫法的WebServer配置:
Apache:
.hatccess按照官方配置就可以;配置host時(shí)配置到public下或者public外面一層的項(xiàng)目根目錄也可以:
DocumentRoot "D:phpStudyWWWzPhalpublic" ServerName goozp.com ServerAlias Options FollowSymLinks ExecCGI AllowOverride All Order allow,deny Allow from all Require all granted
Nginx
大概的配置如下,配置到public下,并定義rewrite規(guī)則:
server { listen 80; server_name www.goozp.com goozp.com; root /data/www/zPhal/public; index index.php index.html index.htm; charset utf-8; client_max_body_size 100M; fastcgi_read_timeout 1800; location / { # Matches URLS `$_GET["_url"]` try_files $uri $uri/ /index.php?_url=$uri&$args; } location ~ .php$ { try_files $uri =404; #fastcgi_pass unix:/var/run/php/php7.0-fpm.sock; fastcgi_pass php-fpm:9000; fastcgi_index /index.php; include fastcgi_params; fastcgi_split_path_info ^(.+.php)(/.+)$; fastcgi_param PATH_INFO $fastcgi_path_info; fastcgi_param PATH_TRANSLATED /data/www/zPhal/public/$fastcgi_path_info; fastcgi_param SCRIPT_FILENAME /data/www/zPhal/public/$fastcgi_script_name; } location ~ /.ht { deny all; } location ~* .(js|css|png|jpg|jpeg|gif|ico)$ { expires max; log_not_found off; access_log off; } }5. 事件管理器,fire寫法不管用
被手冊(cè)誤導(dǎo),理解錯(cuò)誤了。
下面是 錯(cuò)誤 的寫法,在dispatcher中去定義了監(jiān)聽事件:
$di->set("dispatcher", function () { // 創(chuàng)建一個(gè)事件管理器 $eventsManager = new EventsManager(); $media = new Media(); $media->setEventsManager($eventsManager); // 監(jiān)聽分發(fā)器中使用插件產(chǎn)生的事件 $eventsManager->attach( "media", new AliYunOss() ); $dispatcher = new Dispatcher(); $dispatcher->setDefaultNamespace("ZPhalModulesAdminControllers"); $dispatcher->setEventsManager($eventsManager); // 分配事件管理器到分發(fā)器 return $dispatcher; });
然而我想封裝的是文件上傳功能,跟 dispatcher分發(fā)器 沒有任何關(guān)系,所以起不了作用還報(bào)錯(cuò);應(yīng)該注冊(cè)一個(gè)返回DI容器的文件上傳服務(wù):
$di->set("mediaUpload",function (){ // 創(chuàng)建一個(gè)事件管理器 $eventsManager = new EventsManager(); $media = new Media(); $eventsManager->attach( "media", new AliYunOss() ); $media->setEventsManager($eventsManager); return $media; });6.使用模型關(guān)聯(lián)不起作用
扔進(jìn)去的對(duì)象報(bào)錯(cuò);需要給關(guān)聯(lián)的對(duì)象定義alias,通過alias來獲取。
如果是這樣:
$terms = new Terms(); $terms->name = $name; $terms->slug = $slug; $termTaxonomy = new TermTaxonomy(); $termTaxonomy->Terms = $terms; // 這里 $termTaxonomy->taxonomy = $type; $termTaxonomy->save();
在$termTaxonomy->Terms = $terms;這里,Terms是TermTaxonomy Model中定義的關(guān)系的別名(alias);
定義方式如下,在model中:
$this->belongsTo( "term_id", "ZPhalModelsTerms", "term_id", [ "alias" => "Terms", ] );
不起alias別名會(huì)報(bào)錯(cuò)。
7. 插入數(shù)據(jù)時(shí)返回主鍵id通過$model -> getWriteConnection() -> lastInsertId();來獲?。?/p>
$model = new model(); if($model -> create($data)) { $insertId = $model -> getWriteConnection() -> lastInsertId($model -> getSource()); }
或者直接在執(zhí)行之后拿id屬性:
create($data)) { $insertId = $model -> id; }8. model事件 beforeCreate 和字段檢查
在 beforeCreate 事件中定義數(shù)據(jù)表字段的數(shù)據(jù)檢查和數(shù)據(jù)賦值,不生效。
beforeCreate 在執(zhí)行之前就會(huì)檢查字段是否符合要求(validation),所以在beforecreate時(shí)再插入不行,會(huì)報(bào)錯(cuò),需要在執(zhí)行create前就傳值,或者設(shè)置默認(rèn)值。
可以在 beforeValidation 時(shí)進(jìn)行賦值檢查的操作。
9. 操作model保存時(shí),save或update無(wú)效表現(xiàn)為save或者update失敗,且不報(bào)錯(cuò)的問題。
情況:主鍵設(shè)置為兩個(gè)字段,更新時(shí)更新了其中一個(gè)字段。
解決:不應(yīng)該修改主鍵。
參考:https://stackoverflow.com/questions/3838414/can-we-update-primary-key-values-of-a-table
find()與findFirst()返回值數(shù)據(jù)格式是不同的。
加了 column 參數(shù)時(shí)的返回值object里時(shí)不完整的,所以無(wú)法使用save等方法,無(wú)法使用model關(guān)系。
沒有數(shù)據(jù)時(shí),find()返回空數(shù)組,findfrist()返回false
11. PhalconCacheBackendRedis 的 queryKeys()出現(xiàn)以下錯(cuò)誤:Cached keys need to be enabled to use this function (options["statsKey"] == "_PHCR")!
Redis的默認(rèn)配置有一個(gè)參數(shù)為‘_PHCR’前綴,所以queryKeys()時(shí)需要帶上查詢前綴。
12 dispatcher->forward() 分發(fā)后原腳本仍然繼續(xù)執(zhí)行可以加上return阻斷:
$this->dispatcher->forward([ "controller" => "error", "action" => "route404" ]); return;
在分發(fā)后后面的代碼將不再執(zhí)行。
13. 錯(cuò)誤:Encryption key cannot be empty使用cookie時(shí),默認(rèn)會(huì)使用Crypt加密,而使用Crypt加密需要定義一個(gè)全局加密key。
可以禁用cookie加密:
set( "cookies", function () { $cookies = new Cookies(); $cookies->useEncryption(false); return $cookies; } );
或者設(shè)置一個(gè)key:
set( "crypt", function () { $crypt = new Crypt(); $crypt->setKey("#1dj8$=dp?.ak//j1V$"); // 使用你自己的key! return $crypt; } );14. cache刪除失?。簈ueryKeys()之后foreach遍歷循環(huán)delete()刪除失敗
正常刪除時(shí):
$this->cache->delete($key)
如果設(shè)置了前綴,會(huì)在$key自動(dòng)加上前綴。
queryKeys列出來的已經(jīng)帶上了前綴,所以這樣刪除:
$keys = $this->cache->queryKeys(); foreach($keys as $key) { $this->cache->delete($key) }
傳進(jìn)去的key還會(huì)自動(dòng)再加一遍前綴,就找不到緩存了,導(dǎo)致刪除失敗。
解決方法:
用$this->cache->flush()清除所有緩存,但是會(huì)清除所有緩存,所以如果是memcache或者redis緩存可以設(shè)置一下statsKey,避免清除了所有緩存。
或者不使用前綴,就可以正常使用queryKeys()和delete()這條流程。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/26324.html
摘要:組件模板與組件數(shù)據(jù)結(jié)合后生成的節(jié)點(diǎn)樹,將被插入到組件的引用位置上。事件用于子組件向父組件傳遞數(shù)據(jù),可以傳遞任意數(shù)據(jù)。官方文檔往期回顧填坑手冊(cè)小程序生成海報(bào)一拆彈時(shí)刻小程序生成海報(bào)二 showImg(https://user-gold-cdn.xitu.io/2019/6/19/16b6e94bcde767a1?w=1069&h=652&f=jpeg&s=120912); 小程序目錄結(jié)構(gòu)...
摘要:方法,如圖總結(jié)因?yàn)榛叶拳h(huán)境在公司內(nèi)網(wǎng),訪問量較小,相比方法,方法可以暫時(shí)解決灰度測(cè)試時(shí)的緩存問題。但是仍然存在風(fēng)險(xiǎn)。 背景:php做web開發(fā),MVC,phalcon 1.生產(chǎn)與灰度數(shù)據(jù)緩存 原因: service層獲取數(shù)據(jù),有新增數(shù)據(jù)字段; controller層是通過redisCache調(diào)用service接口; redisCache采用redis-file雙緩存結(jié)構(gòu),可能存在...
摘要:海報(bào)生成示例最近智酷君在做小程序生成海報(bào)的項(xiàng)目中遇到一些棘手的問題,在網(wǎng)上查閱了各種資料,也踩扁了各種坑,智酷君希望把這些填坑經(jīng)驗(yàn)整理一下分享出來,避免后來的兄弟重復(fù)掉坑。 showImg(https://segmentfault.com/img/bVbs5V8?w=343&h=517);海報(bào)生成示例 最近智酷君在做[小程序]canvas生成海報(bào)的項(xiàng)目中遇到一些棘手的問題,在網(wǎng)上查閱了...
閱讀 2027·2019-08-30 15:52
閱讀 2990·2019-08-29 16:09
閱讀 1333·2019-08-28 18:30
閱讀 2463·2019-08-26 12:24
閱讀 1109·2019-08-26 12:12
閱讀 2284·2019-08-26 10:45
閱讀 580·2019-08-23 17:52
閱讀 845·2019-08-23 16:03