php中Yaf框架集成zendframework2
php框架 Yaf集成zendframework2, zf2的orm 可以作为独立模块用到yaf中,而且zf2 composer service manger cacheStorage 都可以集成到yaf中。
一:public\index.php 加入composer
chdir(dirname(__DIR__)); // Decline static file requests back to the PHP built-in webserver if (php_sapi_name() === 'cli-server' && is_file(__DIR__ . parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH))) { return false; } // Setup autoloading require 'init_autoloader.php'; // Define path to application directory define("APP_PATH", dirname(__DIR__)); // Create application, bootstrap, and run $app = new Yaf_Application(APP_PATH . "/conf/application.ini"); $app->bootstrap()->run();
根目录 存放 init_autoloader.php
二:导入ZF2 模块组件
vendor\ZF2 见页尾下载包
三:更改bootstrap配置文件
<?php use Zend\ServiceManager\ServiceManager; use Zend\Mvc\Service\ServiceManagerConfig; use Zend\ModuleManager\Listener\ConfigListener; use Zend\ModuleManager\Listener\ListenerOptions; use Zend\ModuleManager\ModuleEvent; class Bootstrap extends Yaf_Bootstrap_Abstract { public function _initConfig() { $config = Yaf_Application::app()->getConfig(); Yaf_Registry::set("config", $config); } public function _initServiceManager() { $configuration = require APP_PATH . '/conf/application.config.php'; $smConfig = isset($configuration['service_manager']) ? $configuration['service_manager'] : array(); $serviceManager = new ServiceManager(new ServiceManagerConfig($smConfig)); $serviceManager->setService('ApplicationConfig', $configuration); $configListener = new ConfigListener(new ListenerOptions($configuration['module_listener_options'])); // If not found cache, merge config if (!$configListener->getMergedConfig(false)) $configListener->onMergeConfig(new ModuleEvent); // If enabled, update the config cache if ($configListener->getOptions()->getConfigCacheEnabled() && !file_exists($configListener->getOptions()->getConfigCacheFile())) { //echo "debug"; $configFile = $configListener->getOptions()->getConfigCacheFile(); $content = "<?php\nreturn " . var_export($configListener->getMergedConfig(false), 1) . ';'; file_put_contents($configFile, $content); } $serviceManager->setService('config', $configListener->getMergedConfig(false)); Yaf_Registry::set('ServiceManager', $serviceManager); } public function _initSessionManager() { Yaf_Registry::get('ServiceManager')->get('Zend\Session\SessionManager'); } public function _initPlugin(Yaf_Dispatcher $dispatcher) { $user = new UserPlugin(); $dispatcher->registerPlugin($user); } }
四:mvc测试
<?php use Zend\Session\Container as SessionContainer; use Zend\Db\TableGateway\TableGateway; class IndexController extends Yaf_Controller_Abstract { public function indexAction() { $adapter = $this->getDbAdapter(); $table = new TableGateway('zt_user', $adapter); $entities = $table->select(); foreach ($entities as $entity) { var_dump($entity->username); } $cache = $this->getStorage(); $cache->setItem('cache', 'cachedata'); echo $cache->getItem('cache'); $this->getLogger()->alert('log'); $this->getView()->assign("content", "Hello World"); } /** * db adapter * @return \Zend\Db\Adapter\Adapter */ public function getDbAdapter() { return Yaf_Registry::get('ServiceManager')->get('Zend\Db\Adapter\Adapter'); } /** * storage * @return \Zend\Cache\Storage\StorageInterface */ protected function getStorage() { return Yaf_Registry::get('ServiceManager')->get('Zend\Cache\Storage\StorageInterface'); } /** * logger * @return \Zend\Log\Zend\Log\Logger */ protected function getLogger() { return Yaf_Registry::get('ServiceManager')->get('Zend\Log\Logger'); } }
这样你访问public下的index.php 会输出hello word字样
一:启动文件 \app\code\Inchoo\Stripe\etc\module.xml
<?xml version="1.0"?> <config xmlns:xsi=" http://www.w3.org/2001/XMLSchema-instance " xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/Module/etc/module.xsd"> <module name="More_Payment" schema_version="1.0.0.0" active="true"> <sequence> <module name="Magento_Sales"/> <module name="Magento_Payment"/> </sequence> <depends> <module name="Magento_Sales"/> <module name="Magento_Payment"/> </depends> </module> </config>
二:配置文件config.xml \app\code\Inchoo\Stripe\etc\config.xml
<?xml version="1.0"?> <config xmlns:xsi=" http://www.w3.org/2001/XMLSchema-instance " xsi:noNamespaceSchemaLocation="../../../Magento/Core/etc/config.xsd"> <default> <payment> <more_payment> <active>1</active> <model>More\Payment\Model\Payment</model> <payment_action>authorize_capture</payment_action> <title>Payment</title> <api_key backend_model="Magento\Backend\Model\Config\Backend\Encrypted" /> <cctypes>AE,VI,MC,DI,JCB</cctypes> <allowspecific>1</allowspecific> <min_order_total>0.50</min_order_total> </more_payment> </payment> </default> </config>
三:后台配置文件 app\code\Inchoo\Stripe\etc\adminhtml\system2.xml
<?xml version="1.0"?> <config xmlns:xsi=" http://www.w3.org/2001/XMLSchema-instance " xsi:noNamespaceSchemaLocation="../../../../Magento/Backend/etc/system_file.xsd"> <system> <section id="payment" translate="label" type="text" sortOrder="400" showInDefault="1" showInWebsite="1" showInStore="1"> <group id="more_payment" translate="label" type="text" sortOrder="50" showInDefault="1" showInWebsite="1" showInStore="1"> <label>Payment</label> <field id="active" translate="label" type="select" sortOrder="1" showInDefault="1" showInWebsite="1" showInStore="0"> <label>Enabled</label> <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model> </field> <field id="title" translate="label" type="text" sortOrder="2" showInDefault="1" showInWebsite="1" showInStore="1"> <label>Title</label> </field> <field id="api_key" translate="label" type="obscure" sortOrder="3" showInDefault="1" showInWebsite="1" showInStore="0"> <label>Api Key</label> <backend_model>Magento\Backend\Model\Config\Backend\Encrypted</backend_model> </field> <field id="debug" translate="label" type="select" sortOrder="4" showInDefault="1" showInWebsite="1" showInStore="0"> <label>Debug</label> <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model> </field> <field id="cctypes" translate="label" type="multiselect" sortOrder="5" showInDefault="1" showInWebsite="1" showInStore="0"> <label>Credit Card Types</label> <source_model>More\Payment\Model\Source\Cctype</source_model> </field> <field id="sort_order" translate="label" type="text" sortOrder="100" showInDefault="1" showInWebsite="1" showInStore="0"> <label>Sort Order</label> </field> <field id="allowspecific" translate="label" type="allowspecific" sortOrder="50" showInDefault="1" showInWebsite="1" showInStore="0"> <label>Payment from Applicable Countries</label> <source_model>Magento\Payment\Model\Config\Source\Allspecificcountries</source_model> </field> <field id="specificcountry" translate="label" type="multiselect" sortOrder="51" showInDefault="1" showInWebsite="1" showInStore="0"> <label>Payment from Specific Countries</label> <source_model>Magento\Directory\Model\Config\Source\Country</source_model> </field> <field id="min_order_total" translate="label" type="text" sortOrder="98" showInDefault="1" showInWebsite="1" showInStore="0"> <label>Minimum Order Total</label> </field> <field id="max_order_total" translate="label" type="text" sortOrder="99" showInDefault="1" showInWebsite="1" showInStore="0"> <label>Maximum Order Total</label> <comment>Leave empty to disable limit</comment> </field> </group> </section> </system> </config>
四:model类 因为我们在config.xml配置了model,所以前台点击保存支付方式的时候 触发
<?php namespace More\Payment\Model; class Payment extends \Magento\Payment\Model\Method\Cc { const CODE = 'more_payment'; protected $_code = self::CODE; protected $_isGateway = true; protected $_canCapture = true; protected $_canCapturePartial = true; protected $_canRefund = true; protected $_canRefundInvoicePartial = true; protected $_stripeApi = false; protected $_minAmount = null; protected $_maxAmount = null; protected $_supportedCurrencyCodes = array('USD'); public function __construct( \Magento\Framework\Event\ManagerInterface $eventManager, \Magento\Payment\Helper\Data $paymentData, \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig, \Magento\Framework\Logger\AdapterFactory $logAdapterFactory, \Magento\Framework\Logger $logger, \Magento\Framework\Module\ModuleListInterface $moduleList, \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate, \Magento\Centinel\Model\Service $centinelService, \Stripe\Api $stripe, array $data = array() ) { parent::__construct($eventManager, $paymentData, $scopeConfig, $logAdapterFactory, $logger, $moduleList, $localeDate, $centinelService, $data); $this->_stripeApi = $stripe; // $this->_stripeApi->setApiKey( // $this->getConfigData('api_key') // ); $this->_minAmount = $this->getConfigData('min_order_total'); $this->_maxAmount = $this->getConfigData('max_order_total'); } /** * 支付捕获方法 * * * @param \Magento\Framework\Object $payment * @param float $amount * @return $this * @throws \Magento\Framework\Model\Exception */ public function capture(\Magento\Framework\Object $payment, $amount) { /** @var Magento\Sales\Model\Order $order */ $order = $payment->getOrder(); /** @var Magento\Sales\Model\Order\Address $billing */ $billing = $order->getBillingAddress(); try { $charge = \Stripe_Charge::create(array( 'amount' => $amount * 100, 'currency' => strtolower($order->getBaseCurrencyCode()), 'description' => sprintf('#%s, %s', $order->getIncrementId(), $order->getCustomerEmail()), 'card' => array( 'number' => $payment->getCcNumber(), 'number' => $payment->getCcNumber(), 'exp_month' => sprintf('%02d',$payment->getCcExpMonth()), 'exp_year' => $payment->getCcExpYear(), 'cvc' => $payment->getCcCid(), 'name' => $billing->getName(), 'address_line1' => $billing->getStreet(1), 'address_line2' => $billing->getStreet(2), 'address_zip' => $billing->getPostcode(), 'address_state' => $billing->getRegion(), 'address_country' => $billing->getCountry(), ), )); $payment ->setTransactionId($charge->id) ->setIsTransactionClosed(0); } catch (\Exception $e) { $this->debugData($e->getMessage()); $this->_logger->logException(__('Payment capturing error.')); throw new \Magento\Framework\Model\Exception(__('Payment capturing error.')); } return $this; } /** * Payment refund * * @param \Magento\Framework\Object $payment * @param float $amount * @return $this * @throws \Magento\Framework\Model\Exception */ public function refund(\Magento\Framework\Object $payment, $amount) { $transactionId = $payment->getParentTransactionId(); try { \Stripe_Charge::retrieve($transactionId)->refund(); } catch (\Exception $e) { $this->debugData($e->getMessage()); $this->_logger->logException(__('Payment refunding error.')); throw new \Magento\Framework\Model\Exception(__('Payment refunding error.')); } $payment ->setTransactionId($transactionId . '-' . \Magento\Sales\Model\Order\Payment\Transaction::TYPE_REFUND) ->setParentTransactionId($transactionId) ->setIsTransactionClosed(1) ->setShouldCloseParentTransaction(1); return $this; } /** * Determine method availability based on quote amount and config data * * @param null $quote * @return bool */ public function isAvailable($quote = null) { if ($quote && ( $quote->getBaseGrandTotal() < $this->_minAmount || ($this->_maxAmount && $quote->getBaseGrandTotal() > $this->_maxAmount)) ) { return false; } // if (!$this->getConfigData('api_key')) { // return false; // } return parent::isAvailable($quote); } /** * Availability for currency * * @param string $currencyCode * @return bool */ public function canUseForCurrency($currencyCode) { if (!in_array($currencyCode, $this->_supportedCurrencyCodes)) { return false; } return true; } }
现在移动端兴起,很多地方都要运用接口为它们传输数据,那么是用xml好还是用json好呢?个人觉得用json是不错的选择。我从以下几点分析一下:
1. xml标签要成对的书写,比如
<list><name>XXX</name><name>XXX</name></list>,而json写法是{"name":"XXX","name":"XXX"},
所以很明显json更节约传输的容量。
2. json生成和解析数据都比较简单,以php为例,只需用一个json_encode函数就可以将一个数组转为json数据了,而xml生成过程相对会麻烦一点。
3. json扩展比较方便,解析速度也较快一点。
所以项目中没有特别的规定,还是用json比较好。
PHP 代码:
$fileName = $_FILES['afile']['name'];
$fileType = $_FILES['afile']['type'];
$fileContent = file_get_contents($_FILES['afile']['tmp_name']);
$dataUrl = 'data:' . $fileType . ';base64,' . base64_encode($fileContent);
$json = json_encode(array(
'name' => $fileName,
'type' => $fileType,
'dataUrl' => $dataUrl,
'username' => $_REQUEST['username'],
'accountnum' => $_REQUEST['accountnum']
));
echo $json;
Html 及 JS 代码
<!DOCTYPE html>
<!--
Copyright 2012 Google Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Author: Eric Bidelman (ericbidelman@chromium.org)
-->
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1" />
<title>xhr.send(FormData) Example</title>
</head>
<body>
<input type="file" name="afile" id="afile" accept="image/*"/>
<script>
document.querySelector('#afile').addEventListener('change', function(e) {
var file = this.files[0];
var fd = new FormData();
fd.append("afile", file);
// These extra params aren't necessary but show that you can include other data.
fd.append("username", "Groucho");
fd.append("accountnum", 123456);
var xhr = new XMLHttpRequest();
xhr.open('POST', 'handle_file_upload.php', true);
xhr.upload.onprogress = function(e) {
if (e.lengthComputable) {
var percentComplete = (e.loaded / e.total) * 100;
console.log(percentComplete + '% uploaded');
}
};
xhr.onload = function() {
if (this.status == 200) {
var resp = JSON.parse(this.response);
console.log('Server got:', resp);
var image = document.createElement('img');
image.src = resp.dataUrl;
document.body.appendChild(image);
};
};
xhr.send(fd);
}, false);
</script>
<!--[if IE]>
<script src="http://ajax.googleapis.com/ajax/libs/chrome-frame/1/CFInstall.min.js"></script>
<script>CFInstall.check({mode: 'overlay'});</script>
<![endif]-->
</body>
</html>
PHP实现方法
在做接口,post传递方式,数据以字符串形式传输,返回数据用JSON封装。
然后就开始各种测试啊。
分享最终的方法:
定义抓取函数:
function http_post_data($url, $data_string) { $ch = curl_init(); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string); curl_setopt($ch, CURLOPT_HTTPHEADER, array( 'Content-Type: application/json; charset=utf-8', 'Content-Length: ' . strlen($data_string)) ); ob_start(); curl_exec($ch); $return_content = ob_get_contents(); ob_end_clean(); $return_code = curl_getinfo($ch, CURLINFO_HTTP_CODE); return array($return_code, $return_content); }
然后是方法:
$url = "路径"; $data = array(); //数组 $data = json_encode($data); //转化为字符串 list($return_code, $return_content) = http_post_data($url, $data); $return_content = json_decode($return_content,1); var_dump($return_content); //输出返回结果。
window.open url 参数post方式传递
最近在做web项目,碰到需要跨页面传递参数的功能,就是那种需要把当前页面的内容带到新开的子窗体中,以前的做法是传一个id过去,然后在新窗口中去读数据库的内容。虽然不怎么麻烦,但是如果内容么有在数据库里保存,仅仅是处以拟稿状态时,就不能实现了,用户还常常认为是个bug。考虑采用get的方式传递,把需要的内容都序列化然后,通过url去传,显得很臃肿,而且get的传递内容长度有限制。于是就想到用post的方式传递,问题在于open方法不能设置请求方式,一般网页的post都是通过form来实现的。如果仅仅模拟form的提交方式,那么open方法里那种可设置窗体属性的参数又不能用。最后想办法整了这么一个两者结合的方式,将form的target设置成和open的name参数一样的值,通过浏览器自动识别实现了将内容post到新窗口中。
比较有意思的是直接通过调用form的submit方法不能触发onsubmit事件,查看了帮助文档,必须手动的触发,否则只能看到页面刷新而没有打开新窗口。代码中只传递了一个参数内容,实际可传递多个。
具体代码如下:
function openPostWindow(url,name,data) { var tempForm = document.createElement("form"); tempForm.id="tempForm1"; tempForm.method="post"; tempForm.action=url; tempForm.target=name; var hideInput = document.createElement("input"); hideInput.type="hidden"; hideInput.name= "content" hideInput.value= data; tempForm.appendChild(hideInput); tempForm.attachEvent("onsubmit",function(){ openWindow(name); }); document.body.appendChild(tempForm); tempForm.fireEvent("onsubmit"); tempForm.submit(); document.body.removeChild(tempForm); return false; } function openWindow(name) { window.open('about:blank',name,'height=400, width=400, top=0, left=0, toolbar=yes, menubar=yes, scrollbars=yes, resizable=yes,location=yes, status=yes'); } </script>
调用:
<A href="javascript:void(0);" onClick="openPostWindow('noWriteSiteInfo.jsp','noWriteSiteInfo','<%=lowerOffset %>');"> 这里是调用; </A>
注意红色部分 如果没有这个,会导致页面上<jsp:include page=""/> 这种页面丢失,这是 链接的href 和 onclick 共存问题,
请求的链接是用的 A 标签,A上同时写了href和onclick事件。对于链接 A 标签而言,当用户鼠标单击的时候,A对象被触发时会首先去执行onclick部分,然后是href。
解决方法就是:
直接把onclick事件写在href中:href="javascript:openPostWindow(。。。)"
还有一种解决方案:<a href="javascript:void(0)" onclick="do();return false;">Test</a>
这样是忽略了href部分,这对于通过onclick传递this,或者无法避开a对象时都有用。
相关文章
基于BootStrap Metronic开发框架经验小结【八】框架功能总体界面介绍
这篇文章主要介绍了基于BootStrap Metronic开发框架经验小结【八】框架功能总体界面介绍 的相关资料,需要的朋友可以参考下...2016-05-14- 今天小编就为大家分享一篇Pandas实现DataFrame按行求百分数(比例数),具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-05-09
- 首先来看下流程:流程原理: 1.通过code获得access_token通过授权,并获取用户的信息(包括用户u_id)(这个u_id在后面的第三方登录表里面叫sina_id,那个表是需要自己建的) 2.查询第三方登录表,如果不存在用户sina_id,分2...2014-05-31
- 这篇文章主要介绍了.net数据库操作框架SqlSugar的简单入门,帮助大家更好的理解和学习使用.net技术,感兴趣的朋友可以了解下...2021-09-22
- 这篇文章主要介绍了记一次EFCore类型转换错误及解决方案,帮助大家更好的理解和学习使用asp.net core,感兴趣的朋友可以了解下...2021-09-22
- 这篇文章主要介绍了c# 常用框架汇总,帮助大家更好的理解和学习使用c#,感兴趣的朋友可以了解下...2021-04-24
- <iframe>也应该是框架的一种形式,它与<frame>不同的是,iframe可以嵌在网页中的任意部分。本文给大家介绍jQuery中iframe的操作(点击按钮新增窗口),需要的朋友参考下吧...2016-04-22
javascript动态的改变IFrame的高度实现自动伸展
动态的改变IFrame的高度,实现IFrame自动伸展,父页面也自动神缩 原理: 在IFrame子页面一加载的时候,调用父IFrame对象,改变其高度 具体实现一: 1、在IFrame的具体页面(就是子页面),添加JavaScript...2013-10-13- Laravel框架我们用到的不多了,但如果使用需要搭配了,下面我们来看一篇关于搭建php Laravel框架教程详解,具体的操作细节如下所示,希望对各位有帮助。 一、安装 Compos...2016-11-25
- 这篇文章主要介绍了Java SSM框架如何添加写日志功能,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-09-25
Framework7 修改模态框默认文字(标题、确认|取消按钮、登录框提示)
下面我们来看一篇关于Framework7 修改模态框默认文字(标题、确认|取消按钮、登录框提示) 的例子,希望这篇文章能够帮助到大家的哦。 Framework7 提供了许多常用的模...2016-10-02ASP.NET中iframe框架点击左边页面链接 右边显示链接页面内容
这篇文章主要介绍了ASP.NET中iframe框架点击左边页面链接,右边显示链接页面内容的实现代码,感兴趣的小伙伴们可以参考一下...2021-09-22BOM系列第二篇之定时器requestAnimationFrame
这篇文章主要介绍了BOM系列第二篇之定时器requestAnimationFrame 的相关资料,非常不错,具有参考借鉴价值,需要的朋友可以参考下...2016-08-24- 这篇文章主要介绍了jQuery取得iframe中元素的常用方法,结合实例形式详细分析了jQuery针对iframe中元素获取技巧及注意事项,需要的朋友可以参考下...2016-01-15
JavaScript实现iframe自动高度调整和不同主域名跨域
这篇文章主要介绍了JavaScript实现iframe自动高度调整和不同主域名跨域,作者通过建立一个代理来同步高度调整,需要的朋友可以参考下...2016-03-01- 这篇文章主要介绍了node.js爬虫框架node-crawler的相关资料,帮助大家利用node.js进行爬虫,感兴趣的朋友可以了解下...2020-10-29
Windows Server 2012 R2或2016无法安装.NET Framework 3.5.1的解决方法
这篇文章主要为大家详细介绍了Windows Server 2012 R2或2016无法安装.NET Framework 3.5.1,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2017-07-06Zend Framework动作助手(Zend_Controller_Action_Helper)用法详解
这篇文章主要介绍了Zend Framework动作助手(Zend_Controller_Action_Helper)用法,详细分析了动作助手Zend_Controller_Action_Helper功能,定义,使用方法与相关实现代码,需要的朋友可以参考下...2016-03-10- 这篇文章主要介绍了在vue中实现嵌套页面(iframe),具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-07-31
- Ray是一种分布式执行框架,便于大规模应用程序和利用先进的机器学习库,今天给大家分享支持python的分布式计算框架Ray详解,感兴趣的朋友一起看看吧...2021-07-29