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