手机浏览 RSS 2.0 订阅 膘叔的简单人生 , 腾讯云RDS购买 | 超便宜的Vultr , 注册 | 登陆
浏览模式: 标准 | 列表分类:PHP

Best MVC Practices

这是一篇来自Yii官方的文章,写在了1.1.6的new fetures里面,值得一看,最起码,你在看完后,下次被人面试的时候,问到什么 是MVC,你可以有回答的东西了。

不多说,上原文,内容也不复杂,所以我就不翻译了(其实是我翻译不来,将就着看看可以,可是要翻译成人人都能看得懂的内容就难了)。。。

原文来自于:http://www.yiiframework.com/doc/guide/1.1/en/basics.best-practices,目前官方也确实没有中文版。

Although Model-View-Controller (MVC) is known by nearly every Web developer, how to properly use MVC in real application development still eludes many people. The central idea behind MVC is code reusability and separation of concerns. In this section, we describe some general guidelines on how to better follow MVC when developing a Yii application.

To better explain these guidelines, we assume a Web application consists of several sub-applications, such as

  • front end: a public-facing website for normal end users;
  • back end: a website that exposes administrative functionality for managing the application. This is usually restricted to administrative staff;
  • console: an application consisting of console commands to be run in a terminal window or as scheduled jobs to support the whole application;
  • Web API: providing interfaces to third parties for integrating with the application.

The sub-applications may be implemented in terms of modules, or as a Yii application that shares some code with other sub-applications.

1. Model 

Models represent the underlying data structure of a Web application. Models are often shared among different sub-applications of a Web application. For example, a LoginForm model may be used by both the front end and the back end of an application; a News model may be used by the console commands, Web APIs, and the front/back end of an application. Therefore, models

  • should contain properties to represent specific data;

  • should contain business logic (e.g. validation rules) to ensure the represented data fulfills the design requirement;

  • may contain code for manipulating data. For example, a SearchForm model, besides representing the search input data, may contain a search method to implement the actual search.

Sometimes, following the last rule above may make a model very fat, containing too much code in a single class. It may also make the model hard to maintain if the code it contains serves different purposes. For example, a News model may contain a method named getLatestNews which is only used by the front end; it may also contain a method named getDeletedNews which is only used by the back end. This may be fine for an application of small to medium size. For large applications, the following strategy may be used to make models more maintainable:

  • Define a NewsBase model class which only contains code shared by different sub-applications (e.g. front end, back end);

  • In each sub-application, define a News model by extending from NewsBase. Place all of the code that is specific to the sub-application in this News model.

So, if we were to employ this strategy in our above example, we would add a News model in the front end application that contains only the getLatestNews method, and we would add another News model in the back end application, which contains only the getDeletedNews method.

In general, models should not contain logic that deals directly with end users. More specifically, models

  • should not use $_GET, $_POST, or other similar variables that are directly tied to the end-user request. Remember that a model may be used by a totally different sub-application (e.g. unit test, Web API) that may not use these variables to represent user requests. These variables pertaining to the user request should be handled by the Controller.

  • should avoid embedding HTML or other presentational code. Because presentational code varies according to end user requirements (e.g. front end and back end may show the detail of a news in completely different formats), it is better taken care of by views.

2. View 

Views are responsible for presenting models in the format that end users desire. In general, views

  • should mainly contain presentational code, such as HTML, and simple PHP code to traverse, format and render data;

  • should avoid containing code that performs explicit DB queries. Such code is better placed in models.

  • should avoid direct access to $_GET, $_POST, or other similar variables that represent the end user request. This is the controller's job. The view should be focused on the display and layout of the data provided to it by the controller and/or model, but not attempting to access request variables or the database directly.

  • may access properties and methods of controllers and models directly. However, this should be done only for the purpose of presentation.

Views can be reused in different ways:

  • Layout: common presentational areas (e.g. page header, footer) can be put in a layout view.

  • Partial views: use partial views (views that are not decorated by layouts) to reuse fragments of presentational code. For example, we use _form.php partial view to render the model input form that is used in both model creation and updating pages.

  • Widgets: if a lot of logic is needed to present a partial view, the partial view can be turned into a widget whose class file is the best place to contain this logic. For widgets that generate a lot of HTML markup, it is best to use view files specific to the widget to contain the markup.

  • Helper classes: in views we often need some code snippets to do tiny tasks such as formatting data or generating HTML tags. Rather than placing this code directly into the view files, a better approach is to place all of these code snippets in a view helper class. Then, just use the helper class in your view files. Yii provides an example of this approach. Yii has a powerful CHtml helper class that can produce commonly used HTML code. Helper classes may be put in an autoloadable directory so that they can be used without explicit class inclusion.

3. Controller 

Controllers are the glue that binds models, views and other components together into a runnable application. Controllers are responsible for dealing directly with end user requests. Therefore, controllers

  • may access $_GET, $_POST and other PHP variables that represent user requests;

  • may create model instances and manage their life cycles. For example, in a typical model update action, the controller may first create the model instance; then populate the model with the user input from $_POST; after saving the model successfully, the controller may redirect the user browser to the model detail page. Note that the actual implementation of saving a model should be located in the model instead of the controller.

  • should avoid containing embedded SQL statements, which are better kept in models.

  • should avoid containing any HTML or any other presentational markup. This is better kept in views.

In a well-designed MVC application, controllers are often very thin, containing probably only a few dozen lines of code; while models are very fat, containing most of the code responsible for representing and manipulating the data. This is because the data structure and business logic represented by models is typically very specific to the particular application, and needs to be heavily customized to meet the specific application requirements; while controller logic often follows a similar pattern across applications and therefore may well be simplified by the underlying framework or the base classes.

Tags: yii

alipay和tenpay等的接口操作记录学习

昨天加班折腾了一下商铺的支付流程,也算是测试了这些接口,不过还是以alipay和tenpay接口居多(即支付宝和财务通接口)

说实话,财务通的接口有点乱,但有一点好处,每个接口的名称都不一样,不同的接口可以很容易认出来,而支付宝就不一样,名称是一样的,但代码和结构不太一样。累了一点。

不过,细分起来这些接口无非就是那几样东西

1、参数,这些都是固定的,有顺序,所以,其实是很方便的,参考一下文档即可。然后做一下MD5进行sign,这些是用来做数据校验的。(有一些接口是对GET参数按照key进行sort而处理的,这种最方便,直接ksort就OK了,如果不是就更方便按顺序录入参数就可以了。)

2、几个固定的URL,接口的URL,notify_url,return_url,了解了这些东西之后就好处理了。

无非就是这些东西,因为都是转向到支付页面进行处理的,所以也不用过多的担心,根据接口来就行了,当然为了要在支付宝或者财务通里看到订单的详细内容,需要那些Desc里写详细,当然你自己平台上的订单号也要传递过去,否则日后无法对帐。

由于我测试 的都是即时到账接口,所以没有什么特别多的经验可以谈,只是我自己了解后做的小记录而已。

Tags: alipay, tenpay, payment

转:因闰秒造成的误差

转帖前的话:这个问题我没有遇到过,事实上,如果不是看到这篇博客,我根本不知道原来还有闰秒这个问题。先看看这篇文章吧。

 

项目中碰到 PHP 和数据库之间,计算存在时间计算误差。大致的情况为根据段时间字符串,例如:

XML/HTML代码
  1. 2012-12-14 00:00:00 UTC  

使用 MySQL 的 UNIX_TIMESTAMP 函数以及 PHP 的 strtotime 计算得出的时间戳,大概有半分钟(差不多有28秒)的误差。

同时,比较‘诡异’的是直接使用当前时间(MySQL 中 UNIX_TIMESTAMP 不带参数,同时 PHP 直接使用 time 函数),却不存在误差(测试脚本)。

排除了 PHP 和 MySQL 之间因为时区设置造成的时间误差 -- 根据经验,如果是时区设置造成的时间误差,应该有几个小时不会那么少。

搜索解决问题期间扫了下这篇帖子,觉得应该是‘闰秒’这玩意造成的问题。搜索 PHP 闰秒相关的配置似乎没有相关的,不过在这里似乎找到了些答案

XML/HTML代码
  1. You also can experience this behavior if your system timezone is with leap seconds. To avoid the problem in this case please run query UPDATE mysql.time_zone SET Use_leap_seconds='N' and restart the server. Please inform us if this helps.  

按照上述的步骤执行,解决了问题。

回过头来,我在工作机(Windows)上测试,发现并不起作用。研究了下,原来闰秒也需要操作系统的支持

XML/HTML代码
  1. 1、对于大多数新的 Linux 内核,在设计时它们都是支持闰秒的,这一点在 REHL4/5 的 2.6.x 内核中得到肯定。   
  2. 2、如果 Linux 系统没有配种某种时间同步机制(比如NTP),那么和闰秒无关,唯一导致的结果只是系统时间会比 UTC时间快一秒。   
  3. 3、Window Time Service 不支持闰秒,包括服务器和客户端。  
回过头来考虑项目中碰到的这种情况,直接使用时间戳存储时间点会更精确些。最后,提供下相关的测试脚本,看看你的环境是否也会有类似的问题。

Tags: leep, 闰秒

常用类NSingleton

常用的一个小工具类吧,为已经使用过的PHP类建立一个实例,也可以防止代码重复加载。

PHP代码
  1. class NSingleton  
  2. {  
  3.     static $instance;  
  4.   
  5.     static public function get($className$autoInit = true) {  
  6.         if (!$className || !is_string($className)) {  
  7.             require_once ('Empty.php');  
  8.             return new NEmpty(); // or return false;  
  9.         }  
  10.         self::set($className$autoInit);  
  11.         return self::$instance;  
  12.     }  
  13.   
  14.     static protected function set($className$autoInit = true) {  
  15.         if (isset(self::$instance[$key]) && self::$instance[$key] != false) {  
  16.             return;  
  17.         }  
  18.         if (!class_exists($className)) {  
  19.             try {  
  20.                 $classFile = sprintf('%s.php',$className);  
  21.                 require_oncesubstr($classFile, 1) ); //remove 'N'  
  22.             } catch (Exception $e) {  
  23.                 trigger_error('class file not exists');  
  24.                 self::$instance[$key] = false;  
  25.             }  
  26.         }  
  27.         $instance = new $className;  
  28.         if ($auoInit && method_exists($instance'init')) {  
  29.             $instance->init();  
  30.         }  
  31.         self::$instance[$key] = $instance;  
  32.     }  
  33. }  
代码写的其实没什么,主要是简化一些操作和代码的加载。。。(用了这个方法加载类,很有可能无法在IDE被识别)

Tags: singleton, instance

Installing Memcached for PHP 5.3 on Windows 7

说出来让我郁闷,memcached -d install。。。一直无法安装成服务,所以,我每次在运行的时候都是memcached -d,窗口不会关闭。。。很丑。

看看老外怎么说,它来自http://shikii.net/blog/installing-memcached-for-php-5-3-on-windows-7/:

Updated:

First off, all credits go to this guy. I’m just listing the steps on how I did it in Windows 7 with PHP 5.3. Also, I tested this using WampServer but I believe it should work on any PHP install.

Install memcached

  1. Download the Memcached Win32 library here: http://code.jellycan.com/memcached. Just get the Win32 binary (direct link). Extract the downloaded archive file in a directory (e.g. c:\memcached). There should be a memcached.exe in there.
  2. Run a command prompt as an administrator. Some info on how to do that here. 【可能就是因为这个,所以我无法装成服务???】
  3. Install memcached as a service. Go to the memcached directory, type and run:

    memcached -d install

    If you get an error saying “MSVCP71.dll is missing”, see this page for a solution.

  4. Start the memcached service by running:

    memcached -d start
  5. You can verify if memcached is running by executing this in the command line:

    wmic process get description, executablepath | findstr memcached.exe

    You should see a result list showing memcached.exe and its full path.

Install PHP Memcache extension (php_memcache.dll)

  1. Chances are you don’t have php_memcache.dll in your PHP extensions yet. You can download a build of it here. Basu has noted in the comments that VC6 builds are no longer available from that link. You can download the correct build here.
  2. The archive should contain php_memcache.dll. Extract the archive to your php extensions directory. On my system (WampServer), this was C:\wamp\bin\php\php5.3.0\ext.
  3. Edit php.ini, add this line to enable the extension:

    extension=php_memcache.dll

    Or if you’re using WampServer, restart it and enable the extension through the WampServer system tray menu.

Test

Test the installation using the sample PHP code here: http://www.php.net/manual/en/memcache.examples-overview.php.

Tags: memcached