vip 模块串讲

来源:互联网 发布:小超市供销存管理优化 编辑:程序博客网 时间:2024/05/11 18:21

模块串讲
一. 新人专题快速入手
1.部署配置
在http://gitlab.tools.vipshop.com/mst/mst-admin-front 拉代码,优先选择git原生支持的ssh协议,即git clone git@gitlab.tools.vipshop.com:mst/mst-admin-front.git 优点就是每次push 和pull 不用输入账号密码,而已速度更快,条件是要将开发电脑的ssh key 添加到gitlab
拉下来的代码目录要修改所有者和用户组,根据nginx的worker进程的所有者
这里写图片描述
和php-fpm 的子进程(与nginx保持一致)
这里写图片描述
所以这里是 chown -R www-data www-data mst-admin-front
这样才有足够权限读写,例如写日志,而不需要给文件777这种不安全的设置
nginx 的配置,看部分配置文件

server {        listen       80;        server_name  mst-admin.vip.vip.com;        proxy_buffer_size   128k;        proxy_buffers   4 256k;        proxy_busy_buffers_size   256k;        #charset koi8-r;        #access_log  logs/host.access.log  main;        root   /Users/liuxing/www/mtms/branches/mtms_0525;        location / {            root   /Users/liuxing/www/mtms/branches/mtms_0525;            index  admin.php;        }        rewrite  ^/css/(.+)$ /client/src/css/$1;        rewrite  ^/common/(.+)$ /client/src/common/$1;        rewrite ^/bower_component/(.+)$  /client/src/bower_component/$1;        rewrite ^/api/(.+)$  /client/src/api/$1;        rewrite ^/demo/(.+)$  /client/src/demo/$1;        rewrite ^/module/(.+)$  /client/src/module/$1;        rewrite ^/prototype/(.+)$ /client/src/prototype/$1;                        set $flag 0;        if ($request !~ "admin.php"){            set $flag "${flag}1";        }        if (!-e $request_filename)        {            set $flag "${flag}2";        }                if ($request ~ ([0-9]+)\.php(.*)$)        {            set $flag "${flag}3";            rewrite ([0-9]+)\.php(.*)$ /index.php/Special/page?page_type_id=1&id=$1&$2;        }        if ($flag = "012")        {            rewrite ^/(.*)$ /index.php/$1;        }        error_page   500 502 503 504  /50x.html;        location = /50x.html {            root   html;        }        location ~ \.php {            fastcgi_pass   127.0.0.1:9000;            fastcgi_index  index.php;            set $real_script_name $fastcgi_script_name;            set $path_info "";            if ( $fastcgi_script_name ~ "^(.+\.php)(/.+)$"){                set $real_script_name $1;                set $path_info $2;            }            fastcgi_param SCRIPT_FILENAME $document_root$real_script_name;            fastcgi_param PATH_INFO $path_info;            include        fastcgi_params;        }    }

2.框架结构与开发流程
MobileFramework,较轻量的web框架,阅读源码比较容易,下面看admin的入口文件
调用了 MobileFramework::init(‘admin’);
核心代码是
require SYS_PATH.’/core/Load.class.php’;
require SYS_PATH.’/core/Hooks.class.php’;
Load::init();
Hooks::init();
Hooks::call(‘pre_system’);

        # 网站根目录地址        define('ROOT', isset($_SERVER['SCRIPT_NAME']) ? rtrim(dirname($_SERVER['SCRIPT_NAME']), '\\') : NULL);        require SYS_PATH.'/core/Common.php';        require SYS_PATH.'/core/Model.class.php';        Application::init();        Route::init();        Dispatcher::init();        Hooks::call('last_system');12345678910111213141516

Load 这个class 的核心功能就是提供了类的自动加载,自动导入share 和new share 目录下的所有类和框架核心类,不用每次调用都require,可以在config/autoload.php 这个文件配置自动加载的类库
Hooks 钩子功能,可以指定调用控制器方法之前或之后执行的脚本,目前项目没怎么使用该功能
Application:init 利用 register_shutdown_function 函数注册 脚本运行结束的回调函数 功能: 将错误日志写到指定文件
Route 路由器,,整理url参数信息, 支持4种路由规则 专题项目使用的是pathinfo 的url解析方法,若开启路由,先解析路由规则
Dispatcher 框架调度类,调用请求action 入口
主要目录作用
service:调用外部接口
bussiness:编写业务逻辑
helper:辅助类
model: 与数据库交互
前后端交互 :目前一种方式是后端返回json,前端调接口。另外一种是用smarty模板引擎,后面会去掉,没用的东西。
还有一种是没用smarty 使用一个PhpView的简单模板
项目大量使用了Factory::create(),一个简单的工厂,实现了最基本的单例模式
开发流程一般是controller 调bussiness bussiness 里调了service或model,就是这么简单。

二.框架和业务代码编写的不足
底层类DB类的链式操作封装不完善,例如当要实现(where ..and ..and (name = .. or name is null))这种形式的操作只能写原生sql,建议完善DB类的方法封装
SimpleUploadHelper 这个类封装了httpPost 这个方法,重用性不高

public static function httpPost($url,$data, $timeout = 30) {        $ch = curl_init();        curl_setopt($ch, CURLOPT_URL, $url);        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);        curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);        curl_setopt($ch, CURLOPT_HEADER, 0);//返回数据不包含头信息        curl_setopt($ch, CURLOPT_FRESH_CONNECT, 1);//刷新链接        curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);        curl_setopt($ch, CURLOPT_POST, true);        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);//POST提交的数据        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);        curl_setopt($ch, CURLOPT_USERAGENT, 'TEST PHP5 Client 1.1 (curl) ' . phpversion());        $result = curl_exec($ch);        $err = curl_error ( $ch );        if (false === $result || !empty ( $err )) {                $errno = curl_errno ( $ch );                $info = curl_getinfo ( $ch );                curl_close ( $ch );                return array (                                'result' => $result,                                'errno' => $errno,                                'msg' => $err,                                'info' => $info                );        }        curl_close($ch);        return $result;    }

建议这个方法放在RequestHelper请求类中,发送请求应该是请求类的职责

再看以下函数

  public static function saveFile($originalName = false)    {        //uploadType上传类型,0为上传至服务本地,1为上传到图片域服务器        $uploadType = 0;        $data = array();        if (!self::$init || !is_uploaded_file(self::$file['tmp_name'])) {            return false;        }        $filename = md5(uniqid(rand(100000, 999999)));        $levelpath = self::makeLevelPath($filename);        $extension = self::getFileExt();        if (!$levelpath) {            return false;        }        /**        * 上传类型名判断        */        if(!preg_match("#jpg|jpeg|png|gif|xls|zip|rar|bmp|xlsx#i", $extension)){            return false;        }        if(preg_match("#jpg|jpeg|png|bmp|gif#i", $extension)){            $uploadType = 1;        }        // 如果上传原名        if($originalName) {            $filename = $filename . '-' . self::getOrgName();        } else {            $filename = $filename . ($extension ? '.' . $extension : '');        }        $relative = $levelpath . '/' . $filename;        $absolute = self::$path . '/' . $relative;        if($uploadType == 0){            if (move_uploaded_file(self::$file['tmp_name'], $absolute)) {                file_put_contents(BASE_PATH . "/upload_log/".date("Ymd").".log", date("Y-m-d H:i:s", time()).", add, $absolute", FILE_APPEND);                return array(                    'absolute' => $absolute,                    'relative' => $relative,                );            }        }else if($uploadType == 1){            if(self::$_isSplit){                $source = 0;                $imgArr = getimagesize(self::$file['tmp_name']);                $ext = end($imgArr);                if(preg_match("#png#i", $ext)){                    $source = imagecreatefrompng(self::$file['tmp_name']);                }else if(preg_match("#jpg|jpeg#i", $ext)){                    $source = imagecreatefromjpeg(self::$file['tmp_name']);                }                $width = imagesx($source);                $height = imagesy($source);                $tmp = 0;                $pics = array();                $data['width'] = $width;                $data['height'] = $height;                // 剪裁                $num = floor($height/200);                $data['average_height'] = (double)number_format($height/$num, 2);                $start_x = $start_y = 0;                for ($i=0; $i < $num; $i++) {                    $croped=imagecreatetruecolor($width, $data['average_height']);                    imagecopy($croped,$source,0,0,$start_x,$start_y,$width,$data['average_height']);                    exec("mkdir -p " . BASE_PATH . Load::config('base', 'split_pic'));                    imagejpeg($croped, BASE_PATH . Load::config('base', 'split_pic') . "split_".$i.$filename);                    imagedestroy($croped);                    $tmp += $data['average_height'];                    $start_y = $tmp;                    $pics[] = BASE_PATH . Load::config('base', 'split_pic') . "split_".$i.$filename;                }                $post_url = IMG_SERVER_URL;                foreach ($pics as $key => $value) {                    $post_data = array(                                            'domain'=>IMG_SERVER_DOMAIN,                                            'apikey'=>IMG_SERVER_AIPKEY,                                            'desc' => '',                                            'filename' => $filename,                                            'tag' => '',                                            'usage' => 'touch',                                            'replaceable' => '1',                                            'md5' => '',                                            //php5.3版本使用                                            'imgfile' => '@' . $value                                            //php5.5版本使用                                            //"imgfile" =>new \CURLFile(realpath($value))                                        );                    $res = self::httpPost($post_url,$post_data);                    $res = json_decode($res, true);                    $data['imgs'][] = $res['url'];                }                $post_data = array(                                        'domain'=>IMG_SERVER_DOMAIN,                                        'apikey'=>IMG_SERVER_AIPKEY,                                        'desc' => '',                                        'filename' => $filename,                                        'tag' => '',                                        'usage' => 'touch',                                        'replaceable' => '1',                                        'md5' => '',                                        //php5.3版本使用                                        'imgfile' => '@' . self::$file['tmp_name']                                        //php5.5版本使用                                        //"imgfile" =>new \CURLFile(realpath(self::$file['tmp_name']))                                    );                $res = self::httpPost($post_url,$post_data);                $res = json_decode($res, true);                $data['source'] = $res['url'];                return $data;            }else{                $post_url = IMG_SERVER_URL;                $post_data = array(                                        'domain'=>IMG_SERVER_DOMAIN,                                        'apikey'=>IMG_SERVER_AIPKEY,                                        'desc' => '',                                        'filename' => $filename,                                        'tag' => '',                                        'usage' => 'touch',                                        'replaceable' => '1',                                        'md5' => '',                                        //php5.3版本使用                                        'imgfile' => '@' . self::$file['tmp_name']                                        //php5.5版本使用                                        //"imgfile" =>new \CURLFile(realpath(self::$file['tmp_name']))                                    );                $res = self::httpPost($post_url,$post_data);                $res = json_decode($res, true);                return array(                        'absolute' => $res['url'],                        'relative' => $res['url'],                    );            }        }        return false;    }

函数太长,阅读性差,在重构:改善既有代码的设计书中 是建议函数中的代码行数原则上不要多于100行,至少其中的图片切割应该提取出单独函数,而且代码编写未达到性能最大化,有些变量在if中需要,在else中并不需要,造成了多余的计算,类似的代码在整个项目中很多地方存在。

5.附录
1. nginx的配置、虚拟主机、负载均衡和反向代理 https://www.zybuluo.com/phper/note/89391
2. git 操作 http://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000
3. 重构:改善既有代码的设计书 http://www.linuxidc.com/Linux/2014-08/105065.htm

0 0
原创粉丝点击