本文將記錄我在Phalcon開發(fā)過程中遇到的問題,以及如何如何解決。
本文首發(fā)在我的博客,我更新之后會更新過來;如果想查看最新的,可以到我的博客:Phalcon填坑手冊:開發(fā)中會遇到的問題和解決方案(不斷更新)
1. 正確地在控制器中獲取參數(shù)一般情況下,GET/POST請求獲取參數(shù):
$this->request->get(參數(shù)名); $this->request->getPost("參數(shù)名")
路由模式下route獲取參數(shù)要用dispatcher->getParam();
route下定義好了參數(shù)名稱可以直接通過參數(shù)名稱來獲取:
this->dispatcher->getParam("參數(shù)名");
route沒有定義好名稱,只是規(guī)則中寫了:params做匹配,可以在控制器中按順序來獲?。?/p>
class NewsController extends Controller { public function showAction($id, $testParam) { echo $id, "|" , $testParam; } }2. 為 url 定制路由
默認自動解析/:controller/:action/:params模式:
在實例化時,不加false參數(shù):
$router = new Router();
url將會自動進行/:controller/:action/:params參數(shù)的解析, 比如https://www.goozp.com/login將會解析成Login controller下的默認action。
當使用路由時,保留默認解析模式有時候會導(dǎo)致解析混亂,比較建議采用完全自定義路由模式。
完全自定義路由,在new時加上false:
$router = new Router(false);
不自動解析/:controller/:action/:params這些規(guī)則, 具體的路由匹配規(guī)則自己來編寫,例如:
$router->add("/login", [ "module" => "admin", "controller" => "login", "action" => "index", ] )->setName("login");
這樣不會因為自動解析而導(dǎo)致url混亂,但是所有url都要自己來定制路由規(guī)則。
3. flash提示重寫后輸出不正確 (未解決)重寫后輸出的html標簽是字符串,外面帶""
4. Config 中 baseURI 的正確設(shè)置因為有Apache+.htaccess文件重寫規(guī)則 或者 nginx配置到public/index.php的重寫規(guī)則,我們不需要項目中的url帶有/publc/index.php。
但是默認是指到了/public/index.php中(比如$_SERVER["PHP_SELF"]獲取從根目錄到當前頁面本身的路徑); 所以,如果有Apache重寫規(guī)則或者nginx配置到public/index.php的重寫配置,我們需要把url設(shè)置為不帶public/index.php的,于是就有了官方的這個設(shè)置:
使用 $_SERVER["PHP_SELF"],并且正則去除/public/index.php
"baseUri" => preg_replace("/public([/])index.php$/", "", $_SERVER["PHP_SELF"]),
這是動態(tài)寫法,這種寫法的問題在于 $_SERVER["PHP_SELF"] 的不確定性,返回的值將根據(jù) Apache 或 nginx 配置的 root,是否配置host或者域名,$_SERVER["PHP_SELF"]會有不同的返回值。這樣的話上面寫法前面的正則并不是全部兼容的,所以這樣寫調(diào)試起來就稍麻煩。
簡單一點,用靜態(tài)寫法:
設(shè)置host或者配置域名
"baseUri" => "/",
如果是想在localhost下直接打開,則需要加上項目外層目錄名,例如:
"baseUri" => "/zphal/",
這樣的話,我們在定義url服務(wù)的時候只需要把這個定義的配置傳進去:
$di->setShared("url", function () { $config = $this->getConfig(); $url = new UrlResolver(); $url->setBaseUri($config->application->baseUri); // baseUri return $url; });
以上寫法的WebServer配置:
Apache:
.hatccess按照官方配置就可以;配置host時配置到public下或者public外面一層的項目根目錄也可以:
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寫法不管用
被手冊誤導(dǎo),理解錯誤了。
下面是 錯誤 的寫法,在dispatcher中去定義了監(jiān)聽事件:
$di->set("dispatcher", function () { // 創(chuàng)建一個事件管理器 $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)系,所以起不了作用還報錯;應(yīng)該注冊一個返回DI容器的文件上傳服務(wù):
$di->set("mediaUpload",function (){ // 創(chuàng)建一個事件管理器 $eventsManager = new EventsManager(); $media = new Media(); $eventsManager->attach( "media", new AliYunOss() ); $media->setEventsManager($eventsManager); return $media; });6.使用模型關(guān)聯(lián)不起作用
扔進去的對象報錯;需要給關(guān)聯(lián)的對象定義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別名會報錯。
7. 插入數(shù)據(jù)時返回主鍵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í)行之前就會檢查字段是否符合要求(validation),所以在beforecreate時再插入不行,會報錯,需要在執(zhí)行create前就傳值,或者設(shè)置默認值。
可以在 beforeValidation 時進行賦值檢查的操作。
9. 操作model保存時,save或update無效表現(xiàn)為save或者update失敗,且不報錯的問題。
情況:主鍵設(shè)置為兩個字段,更新時更新了其中一個字段。
解決:不應(yīng)該修改主鍵。
參考:https://stackoverflow.com/questions/3838414/can-we-update-primary-key-values-of-a-table
find()與findFirst()返回值數(shù)據(jù)格式是不同的。
加了 column 參數(shù)時的返回值object里時不完整的,所以無法使用save等方法,無法使用model關(guān)系。
沒有數(shù)據(jù)時,find()返回空數(shù)組,findfrist()返回false
11. PhalconCacheBackendRedis 的 queryKeys()出現(xiàn)以下錯誤:Cached keys need to be enabled to use this function (options["statsKey"] == "_PHCR")!
Redis的默認配置有一個參數(shù)為‘_PHCR’前綴,所以queryKeys()時需要帶上查詢前綴。
12 dispatcher->forward() 分發(fā)后原腳本仍然繼續(xù)執(zhí)行可以加上return阻斷:
$this->dispatcher->forward([ "controller" => "error", "action" => "route404" ]); return;
在分發(fā)后后面的代碼將不再執(zhí)行。
13. 錯誤:Encryption key cannot be empty使用cookie時,默認會使用Crypt加密,而使用Crypt加密需要定義一個全局加密key。
可以禁用cookie加密:
set( "cookies", function () { $cookies = new Cookies(); $cookies->useEncryption(false); return $cookies; } );
或者設(shè)置一個key:
set( "crypt", function () { $crypt = new Crypt(); $crypt->setKey("#1dj8$=dp?.ak//j1V$"); // 使用你自己的key! return $crypt; } );14. cache刪除失?。簈ueryKeys()之后foreach遍歷循環(huán)delete()刪除失敗
正常刪除時:
$this->cache->delete($key)
如果設(shè)置了前綴,會在$key自動加上前綴。
queryKeys列出來的已經(jīng)帶上了前綴,所以這樣刪除:
$keys = $this->cache->queryKeys(); foreach($keys as $key) { $this->cache->delete($key) }
傳進去的key還會自動再加一遍前綴,就找不到緩存了,導(dǎo)致刪除失敗。
解決方法:
用$this->cache->flush()清除所有緩存,但是會清除所有緩存,所以如果是memcache或者redis緩存可以設(shè)置一下statsKey,避免清除了所有緩存。
或者不使用前綴,就可以正常使用queryKeys()和delete()這條流程。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/26324.html
摘要:組件模板與組件數(shù)據(jù)結(jié)合后生成的節(jié)點樹,將被插入到組件的引用位置上。事件用于子組件向父組件傳遞數(shù)據(jù),可以傳遞任意數(shù)據(jù)。官方文檔往期回顧填坑手冊小程序生成海報一拆彈時刻小程序生成海報二 showImg(https://user-gold-cdn.xitu.io/2019/6/19/16b6e94bcde767a1?w=1069&h=652&f=jpeg&s=120912); 小程序目錄結(jié)構(gòu)...
摘要:方法,如圖總結(jié)因為灰度環(huán)境在公司內(nèi)網(wǎng),訪問量較小,相比方法,方法可以暫時解決灰度測試時的緩存問題。但是仍然存在風(fēng)險。 背景: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),可能存在...
摘要:海報生成示例最近智酷君在做小程序生成海報的項目中遇到一些棘手的問題,在網(wǎng)上查閱了各種資料,也踩扁了各種坑,智酷君希望把這些填坑經(jīng)驗整理一下分享出來,避免后來的兄弟重復(fù)掉坑。 showImg(https://segmentfault.com/img/bVbs5V8?w=343&h=517);海報生成示例 最近智酷君在做[小程序]canvas生成海報的項目中遇到一些棘手的問題,在網(wǎng)上查閱了...
閱讀 2076·2019-08-30 15:52
閱讀 3062·2019-08-29 16:09
閱讀 1380·2019-08-28 18:30
閱讀 2517·2019-08-26 12:24
閱讀 1161·2019-08-26 12:12
閱讀 2323·2019-08-26 10:45
閱讀 627·2019-08-23 17:52
閱讀 965·2019-08-23 16:03