摘要:在使用這個的時候有的數據是需要加上的,因為不然如果內容里面帶有了這種就會出問題。修改默認的解析所使用的類為新建的擴展類如果說字符串需要使用的時候需要設置經過本次的修改算是對如何修改和擴展有了一定的認識。
最近一直在學習Yii2框架,可能是一直以來對它的青睞,讓我難以對其它框架再產生興趣,學習中遇到了許多問題,于是把問題和解決辦法也記錄下來,這樣方便以后復習和交流。
目錄擴展XmlResponseFormatter
在原有的Yii2框架上,新建一個api應用
配置Yii2 request Parser使之可以通過Yii::$app->request->post()來接收 xml 和 json的數據
使用 TimestampBehavior 來自動填充 created_at 和 updated_at
擴展XmlResponseFormatter在做微信接口測試的時候發現,每次返回數據的時候都是自己寫的 xml 信息然后 echo 出來,今天突然看到了 Yii::$app->response->format = Response::FORMAT_XML; 原來通過這個就可以設置返回的數據為 xml ,當然 response 這個類在 Controller 里面是沒有加載的,所以首先得加載一下 use yiiwebResponse; ,最后把需要返回的數據用數組的形式來返回即可:
response->format = Response::FORMAT_XML; return [ "ToUserName"=>$postObject->FromUserName, "FromUserName"=>$postObject->ToUserName, "CreateTime"=>time(), "MsgType"=>"music", "Music"=>[ "Title"=>$recognition, "Description"=>$decode, "MusicUrl"=>$musicurl, "HQMusicUrl"=>$musicurl, ] ]; }
這樣使用之后發現請求得到的結果是:
1416207112 music maps maroon5 120976464.mp3?xcode=7ba3137f5fd742bcba7a6f5a2ffb7764172503013bacbdc8 http://zhangmenshiting.baidu.com/data2/music/120976464/120976464.mp3?xcode=7ba3137f5fd742bcba7a6f5a2ffb7764172503013bacbdc8 http://zhangmenshiting.baidu.com/data2/music/120976464/120976464.mp3?xcode=7ba3137f5fd742bcba7a6f5a2ffb7764172503013bacbdc8
問題就來了,微信需要的格式是前外層以
Yii::$app->response->formatters = [Response::FORMAT_XML=> ["class"=>yiiwebXmlResponseFormatter", "rootTag"=>"xml"];
通過這樣設置之后,最外層的 response 終于變成了 xml,又發現了一個問題,那就是我的內容里面根本就沒有SimpleXMLElement相關的東西,這個怎么會多出來?回看了一下邏輯代碼發現有:
$postObject = simplexml_load_string($postStr, "SimpleXMLElement", LIBXML_NOCDATA);
最后只能在return的時候加上類型轉換為字符串,這下終于恢復正常了。
return [ "ToUserName"=>(string)$postObject->FromUserName, "FromUserName"=>(string)$postObject->ToUserName, // ... ]
在使用這個的時候有的數據是需要加上 CDataSection() 的,因為不然如果內容里面帶有了 < 這種就會出問題。這個確實讓我頭疼了很久,首先看了一下源代碼原來的類 XmlResponseFormatter, 確實無法滿足相應的需求,滿足不了需求就只能擴展了
step1. 在應用下創建一個 component 目錄
step2. 在component目錄下新建一個 MyXmlResponseFormatter.php 的文件
step3. 實現這個類
$value) { if (is_int($name) && is_object($value)) { $this->buildXml($element, $value); } elseif (is_array($value) || is_object($value)) { $child = new DOMElement(is_int($name) ? $this->itemTag : $name); $element->appendChild($child); // 主要就是修改這一個點,如果值是一個數組,并且含有 CDATA 的,那么就直接創建一個 CdataSection 節點, // 而不把它本身當作列表再回調。 if(array_key_exists(self::CDATA, $value)){ $child->appendChild(new DOMCdataSection((string) $value[0])); }else{ $this->buildXml($child, $value); } } else { $child = new DOMElement(is_int($name) ? $this->itemTag : $name); $element->appendChild($child); $child->appendChild(new DOMText((string) $value)); } } } else { $element->appendChild(new DOMText((string) $data)); } } }
step4. 修改默認的 xml 解析所使用的類為新建的擴展類
Yii::$app->response->formatters = [ Response::FORMAT_XML=> ["class"=>"weixincomponentMyXmlResponseFormatter"] ];
step5. 如果說字符串需要使用 CDATA 的時候需要設置
use weixincomponentMyXmlResponseFormatter as MXRF; return [ "ToUserName"=>[$postObj->FromUserName,MXRF::CDATA=>true], "FromUserName"=>[$postObj->ToUserName,MXRF::CDATA=>true], "CreateTime"=>time(), "MsgType"=>"music", "Music"=>[ "Title"=>[$recognition,MXRF::CDATA=>true], "Description"=>[$decode,MXRF::CDATA=>true], "MusicUrl"=>[$musicurl,MXRF::CDATA=>true], "HQMusicUrl"=>[$musicurl,MXRF::CDATA=>true], ] ];
經過本次的修改算是對如何修改和擴展Yii2 有了一定的認識。
在原有的Yii2框架上,新建一個api應用在做東西的時候需要清晰的結構和邏輯,這樣做出來的東西相對來說會比較漂亮,所以為了api我們可能得新建一個應用,這里面全是api相關的程序,我通過Google “yii2 create new application”,“yii2 add new application”,都沒有找到相要的答案,于是只能開動自己的腦筋了。
$ cp -a environments/dev/frontend environments/dev/api
$ cp -a environments/prod/frontend environments/prod/api
# file: environments/index.php [ "setWritable" => [ // ... 在原來的后面添加上 "api/runtime", "api/web/assets" ], "setCookieValidationKey" => [ // ... 在原來的后面添加上 "api/config/main-local.php", ], ], "Production" => [ // 這里和上面一樣的添加 ], ];
創建相應的目錄:
$ mkdir -p api/{assets,config,controllers,models,runtime,web/assets}
$ touch api/{assets,config,controllers,models,runtime,web/assets}/.gitkeep
復制配置文件:
$ cp -a frontend/config/params.php frontend/config/main.php frontend/config/bootstrap.php frontend/config/.gitignore api/config
$ cp frontend/runtime/.gitignore api/runtime/
$ cp frontend/web/.gitignore api/web
# file api/config/main.php return [ "id" => "app-api", // ... "controllerNamespace" => "apicontrollers", ] # file common/config/bootstrap.php Yii::setAlias("api", dirname(dirname(__DIR__)) . "/api"); // 配置的其它信息看自己的需求而定
$ ./init
新建一個Controller來測試一下:
# file: api/controllers/SiteController.php然后通過瀏覽器訪問相應的地址 http://hostname/api/web/index.php?r=site/index 能出來 test 則代表 ok 啦,以上步驟都是一步步的嘗試和查看源代碼得來的,可能會有不規范的地方,若有不對的地方請到 Github (yii2-usage)上留言。
配置Yii2 request Parser使之可以通過Yii::$app->request->post()來接收 xml 和 json的數據大家都知道 Yii2 接收 POST 數據是使用 Yii::$app->request->post();,但是如果發送過來的數據格式是 json 或 xml 的時候,通過這個方法就無法獲取到數據了,Yii2 這么強大的組件型框架肯定想到了這一點。
對于 json 的解析 Yii2 已經寫好了 [[JsonResponseFormatter]] ,在配置文件里面配置一下即可使用。
# file app/config/main.php "components" =>[ "request" => [ "parsers" => [ "application/json" => "yiiwebJsonParser", "text/json" => "yiiwebJsonParser", ], ], ],配置好之后訪問提交過來的數據就太簡單啦
# json raw data {"username": "bob"} # access data $post_data = Yii::$app->request->post(); echo $post_data["username"]; # or echo Yii::$app->request->post("username");可以通過 composer 添加依賴:bobchengbin/yii2-xml-request-parser 來完成
# file app/config/main.php "components" =>[ "request" => [ "parsers" => [ "text/xml" => "bobchengbinYii2XmlRequestParserXmlRequestParser", "application/xml" => "bobchengbinYii2XmlRequestParserXmlRequestParser", "application/json" => "yiiwebJsonParser", "text/json" => "yiiwebJsonParser", ], ], ],經過上面的三步之后,就可以直接訪問提交過來的 xml 數據了。
# raw data# access data Yii::$app->request->post("username"); 這樣不管別人傳過來的數據是 html、json、xml 格式都可以非常方便的獲取了,在和各種接口打交道的時候用上這個可以方便太多了。
使用 TimestampBehavior 來自動填充 created_at 和 updated_atYii2 官方默認提供了一個 TimestampBehavior 來方便我們來自動填充 created_at 和 updated_at ,它會自動在你插入新數據的時候幫你填充這兩個值為當前時間,當然你也可以設置成別的時間,當你更新數據的時候它會自動把 updated_at 改成最后更新的時間。
我創建了一個 user_weixin 表,然后設置 created_at 和 updated_at 兩個字段為 datetime 類型,并在相應的 Model 里面使用上 TimestampBehavior
# file app/models/UserWeixin.php然后正常的調用保存數據,發現那兩個字段的值均為 "0000-00-00 00:00:00",看到這個感覺甚是奇怪,去看了一下默認生成的用戶模型,common/models/User.php,發現它也沒有做其它的別的操作就可以的啊,我這樣為什么不行呢,去看了一下表結構,發現系統創建的 user 表的兩個字段是使用的 int 類型,而不是 datetime,于是把 user_weixin 表的兩個字段也改成了 int 類型,再測試一次發現好了。
不甘心的我去看了一下 TimestampBehavior 類的注釋,發現確實沒有說明這個問題,所以大家在聲明 created_at 和 updated_at 字段類型的時候需要注意一下。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/20881.html
摘要:本文討論通過工具安裝框架并優化過程中遇到的問題,約定讀者對基本原理有一定了解,并且有安裝框架的實際經驗。這個命令是優化包的關鍵一環。命令要謹慎使用。 本文討論通過composer工具安裝Yii2框架并優化Vendor過程中遇到的問題,約定讀者對composer基本原理有一定了解,并且有安裝Yii2框架的實際經驗。 在Yii2社區里經常會遇到一類問題,那就是 安裝完官方推薦的版本后1 ...
摘要:版本這個原因是因為禁用了函數,所以我們需要更改找到的配置文件輸入命令會出現兩個相關的地址配置文件在中找到,打開之后搜索將去掉,保存處理這個問題有兩種方式,第一種是修改在中加上,應該是禁用的意思還有一種方式就是將升級到以上,這個錯誤就不會出現 codeception版本 v2.1.8 shell_exec PHP Warning: shell_exec() has been disabl...
摘要:新手,不擅長寫,純粹只是分享一下自己遇到的問題供大家參考一下這個插件,就是帶搜索功能的下拉選擇框效果如圖使用前先確定自己的項目安裝了,如果沒有的話就用安裝一下使用的時候先在頭部引用插件如果表單是,可以使用下面代碼是鍵值對數組,下面所聲明的 新手,不擅長寫js,純粹只是分享一下自己遇到的問題供大家參考一下 select2這個插件,就是帶搜索功能的下拉選擇框效果如圖:showImg(ht...
摘要:新手,不擅長寫,純粹只是分享一下自己遇到的問題供大家參考一下這個插件,就是帶搜索功能的下拉選擇框效果如圖使用前先確定自己的項目安裝了,如果沒有的話就用安裝一下使用的時候先在頭部引用插件如果表單是,可以使用下面代碼是鍵值對數組,下面所聲明的 新手,不擅長寫js,純粹只是分享一下自己遇到的問題供大家參考一下 select2這個插件,就是帶搜索功能的下拉選擇框效果如圖:showImg(ht...
閱讀 3125·2021-11-23 09:51
閱讀 1992·2021-09-09 09:32
閱讀 1096·2019-08-30 15:53
閱讀 2967·2019-08-30 11:19
閱讀 2478·2019-08-29 14:15
閱讀 1444·2019-08-29 13:52
閱讀 564·2019-08-29 12:46
閱讀 2831·2019-08-26 12:18