锁定老帖子 主题:PHP程序员是否应该使用自己写的框架
精华帖 (0) :: 良好帖 (5) :: 新手帖 (0) :: 隐藏帖 (5)
|
|
---|---|
作者 | 正文 |
发表时间:2012-05-02
achun 写道 我认为如果项目有一定规模,一定要有自己核心稳定的技术leader,
那技术方案就应该由leader决定. 当然,如果让我选方案,我是不会用目前常见的框架的,不是因为人家的框架不好,而恰恰是因为维护成本高的问题, 个人感觉流行的PHP框架都有一个共性,那就是庞大,那些不庞大的都不能流行. PHP之下不应该出现庞大框架,因为这违背了PHP的精神,PHP追求的就是简单快速. 但是一个不庞大的框架,相信有一定水准的PHPer都可以写出来. 就算你用框架也不能避免混合着SQL语句的代码,因为php本来就是这样的, PHP的一个特有现象: 框架要流行就要全面大. 但是大项目用这样的框架不见得合适,因为你项目够大,就要招聘足够实力的技术,但是有这样实力的技术都会按照项目需求快速构建一个定制的框架. 至于你说的,后续招的人不合适的问题,那和你用啥框架无关的. 对于php招人,如果不能快速上手一个陌生的框架,那就不是个合适的人选. 而对于一个php框架,如果不能让人上手,那也不是好的框架. 深有同感 ........ |
|
返回顶楼 | |
发表时间:2012-05-02
个人感觉 主要还是在于 模块切分上面 至于底层框架 我觉得并不是 项目进度慢的 主要问题
.......... |
|
返回顶楼 | |
发表时间:2012-05-02
有自己开发的框架可以用,前提是必须简单易学,比大框架要简单n倍,半天能学会才行。
如果自己开发的框架比cakephp还复杂,能赶上zf,那不如使用大的框架 |
|
返回顶楼 | |
发表时间:2012-05-02
想我没做的一个模块出来就能上线一个模块,没有花多少个月。
什么项目4个月才做出一半啊 |
|
返回顶楼 | |
发表时间:2012-05-04
个人觉得 thinkphp 比较好用。
如果需要绝对的性能,建议考虑一下 http://code.google.com/p/slightphp/ zend framework当类库。 |
|
返回顶楼 | |
发表时间:2012-05-04
再NB的人没用对地方也没用,就好比一个JAVA大牛去做c#一样
|
|
返回顶楼 | |
发表时间:2012-05-04
xiaokang1582830 写道 再NB的人没用对地方也没用,就好比一个JAVA大牛去做c#一样
是认为PHP不应该有框架吗?还是认为PHP程序员不应该在生产环境使用自己写的框架? |
|
返回顶楼 | |
发表时间:2012-05-04
如果你在一个研究机构,有足够的时间,可以自己写框架。 如果你在一个商业机构。别人怎么写,你也怎么写。你写过的代码就会成为你将来的“框架”。哪怕是 paste & copy. 框架无非是一些规范和约束,从来没有“银弹”。没有积累相当的coding经验,企图通过寻找框架 来提高效率是舍本求末。 对于web开发,我一直有点困惑。微软、IBM等巨头在商业开发中都有各自成熟的开发框架,只是对于 单兵或两三人开发又不适用。于是大家又陷入了开源项目或“重新发明轮子”的困惑中。 其实从java 的 web开发中可见一斑。无论是胖客户还是瘦客户。无论是web 2.0 抑或是 组件式的 JSF。 沸沸扬扬折腾一大圈,还是最初那个 基于 MVC的STRUTS最好用。为什么? web这种无状态连接方式应用,还是 采用MVC最靠谱。 总之,我想要么就啥框架别用。要么就采用大公司的框架。 当然,如果你是开公司的,从卖服务的角度作长远打算,那是非得有个框架不可了。 一年多不做技术了,不当之处,还望指正。 |
|
返回顶楼 | |
发表时间:2012-05-05
eserver220 写道 如果你在一个研究机构,有足够的时间,可以自己写框架。 如果你在一个商业机构。别人怎么写,你也怎么写。你写过的代码就会成为你将来的“框架”。哪怕是 paste & copy. 框架无非是一些规范和约束,从来没有“银弹”。没有积累相当的coding经验,企图通过寻找框架 来提高效率是舍本求末。 对于web开发,我一直有点困惑。微软、IBM等巨头在商业开发中都有各自成熟的开发框架,只是对于 单兵或两三人开发又不适用。于是大家又陷入了开源项目或“重新发明轮子”的困惑中。 其实从java 的 web开发中可见一斑。无论是胖客户还是瘦客户。无论是web 2.0 抑或是 组件式的 JSF。 沸沸扬扬折腾一大圈,还是最初那个 基于 MVC的STRUTS最好用。为什么? web这种无状态连接方式应用,还是 采用MVC最靠谱。 总之,我想要么就啥框架别用。要么就采用大公司的框架。 当然,如果你是开公司的,从卖服务的角度作长远打算,那是非得有个框架不可了。 一年多不做技术了,不当之处,还望指正。 框架引入规范和约束正是项目开发的根本需求,这不算是舍本求末,因为很多时候这些规范和约束是必须的,无论是从安全还是持续性上都需要的,简单的举个例子,数据库操作有很多安全和效率的问题,如果不采用框架或者数据库封装类,那么散乱的代码一旦出问题,你就去挨个扒拉吧,但是有了框架和数据库封装类那问题解决起来就快速的多. 因此作为一个开发者研究和选择框架是不可少的一个方向.当然怎么样才算合适的框架这个每个人都有自己的不同意见. |
|
返回顶楼 | |
发表时间:2012-05-05
最后修改:2012-05-05
我这边现在用了我写的IWP框架 这个过程不经历不知道 痛并快乐中...
慢慢走吧...路 大框架又需要自定义 ... 这也不是个轻松的活 .....
如果 出名的框架真那么好 为什么大家还要自己写...
像 ZF CAKEPHP 这些很强 .... 但如果不深入 定制似乎很难...
比如 zf 的 控制器 这块 一般的人根本看不懂里面的实现机制........
而作为技术指导者,你又必须去告知他们实现机制,而不是给个文档就能了事,出了问题就让他上网找...这都是不现实的 而一旦被深入提问,你就悲催了.... 难不成你告诉他 就这么用,一知半解??? 那下次这个问题 是否又会重复被提问
像 lz 提出的 任务延迟案例... 我个人觉得绝对不是框架的问题,作为框架实现者 之所以实现框架 就是为了节省开发时间,提高开发效率的
在项目开发中,延迟的可能性很多,例如:
1. 需求是否总跳... 这点大部分的人都在为此死B的无眠.... 2. 开发人员是否到位... 分工是否明确... 3. 模块拆分,功能设计,任务分配 是否..... 4. 你招的那个大拿是否有带队的经验.....
php 开发框架 说白了 就是 MVC + db封装类(例如 啥子 orm 的)
复杂度与java相比 应该是 0.01 ....
至于 现在出现问题,我觉得不应该 推卸全部责任到 这位大拿的框架上.... 而是整个团队需要静下心来 总结前期工作的失误过程
找出可以修改的地方,予以改正.... 互相指责能解决问题么????
对于 lz , 如果可能 可以把那位大拿写的框架 给我看看.. 我可以帮忙分析下 复杂度........ <?php /** * 指示用户试图访问的控制器方法不允许该用户访问 * */ class Core_Mvc_Dispatcher_Exception_CheckFailed extends Exception { public $controllerName; public $actionName; public $roles; public $act; /** * 构造函数 * * @param string $controllerName * @param string $actionName * @param array $act 资源授予的角色 * @param array $roles 当前访问用户具有的角色信息 */ function __construct($controllerName, $actionName, $act = null, $roles = null) { $this->controllerName = $controllerName; $this->actionName = $actionName; $this->act = $act; $this->roles = $roles; $msg = sprintf('拒绝访问控制器动作: "%s::%s".', $controllerName, $actionName); parent::__construct($msg); } } /** * 控制器类没有找到 */ class Core_Mvc_Dispatcher_Exception_MissingController extends Exception { /** * 控制器的名字 * * @var string */ public $controllerName; /** * 控制器类名称 * * @var string */ public $controllerClass; /** * 动作名 * * @var string */ public $actionName; /** * 动作方法名 * * @var string */ public $actionMethod; /** * 调用参数 * * @var mixed */ public $arguments; /** * 控制器的类定义文件 * * @var string */ public $controllerClassFilename; /** * 构造函数 * * @param string $controllerName * @param string $actionName * @param mixed $arguments * @param string $controllerClass * @param string $actionMethod * @param string $controllerClassFilename */ function __construct($controllerName, $actionName, $arguments = null, $controllerClass = null, $actionMethod = null, $controllerClassFilename = null) { $this->controllerName = $controllerName; $this->actionName = $actionName; $this->arguments = $arguments; $this->controllerClass = $controllerClass; $this->actionMethod = $actionMethod; $this->controllerClassFilename = $controllerClassFilename; parent::__construct($this->__msg__()); } function __msg__(){ return sprintf('缺少控制器 "%s".', $this->controllerName); } } /** * 控制器动作没有找到 * */ class Core_Mvc_Dispatcher_Exception_MissingAction extends Core_Mvc_Dispatcher_Exception_MissingController { function __msg__(){ return sprintf('缺少控制器方法 "%s::%s()".',$this->controllerClass,$this->actionMethod); } } /** * Core_Mvc_Dispatcher_FailedHandler 处理分发过程中出现的错误 * */ interface Core_Mvc_Dispatcher_FailedHandler { function denyAccess(Core_Mvc_Dispatcher_Exception_CheckFailed $ex); function missingController(Core_Mvc_Dispatcher_Exception_MissingController $ex); function missingAction(Core_Mvc_Dispatcher_Exception_MissingAction $ex); function otherCause(Exception $ex); } /** * Core_Mvc_Dispatcher 分析请求,并转发到合适的 Controller 对象处理 * * 注意: * * 1. action 名称中不能包含 _ 字符 * 2. * */ abstract class Core_Mvc_Dispatcher { const controllerAccessor = 'controller'; const actionAccessor = 'action'; const defaultController = 'Application'; const defaultAction = 'index'; const actionMethodPrefix = 'action'; /** * 保存了请求信息的数组 * * @var array */ protected $_request; /** * 原始的请求信息数组 * * @var array */ protected $_requestBackup; /** * 请求分发失败时的错误处理器对象 * * @var Core_Mvc_Dispatcher_FailedHandler */ protected $_dispatchingFailedHandler = null; /** * 构造函数 * * @param array $request */ function __construct(array $request = null) { $this->_requestBackup =& $request; $r = array_change_key_case($request, CASE_LOWER); $data = array(Core_Mvc_Dispatcher::controllerAccessor => null, Core_Mvc_Dispatcher::actionAccessor => null); if (isset($r[Core_Mvc_Dispatcher::controllerAccessor])) { $data[Core_Mvc_Dispatcher::controllerAccessor] = $r[Core_Mvc_Dispatcher::controllerAccessor]; } if (isset($r[Core_Mvc_Dispatcher::actionAccessor])) { $data[Core_Mvc_Dispatcher::actionAccessor] = $r[Core_Mvc_Dispatcher::actionAccessor]; } $this->_request = $data; // 设置错误处理类 -- 必须指定 $dispatchingFailedClass = $this->getDispatchingFailedClass(); Core_Autoloader::loadClass($dispatchingFailedClass,true); $dispatchingFailedHandler = new $dispatchingFailedClass(); if ($dispatchingFailedHandler instanceof Core_Mvc_Dispatcher_FailedHandler){ $this->_dispatchingFailedHandler = $dispatchingFailedHandler; return; } throw new Core_Exception_TypeMismatch('dispatchingFailedClass','Core_Mvc_Dispatcher_FailedHandler',$dispatchingFailedClass); } /** * 设置 转发分发 * * fixed: 修正 控制器转发请求 后 $_GET/$_REQUEST 中参数不同步的问题 * * @param string $controllerName * @param string $actionName * @param array $args * * @return Core_Mvc_Dispatcher */ function setForward($controllerName,$actionName, array $args=null){ $this->setControllerName($controllerName); $this->setActionName($actionName); $controllerName = $this->getControllerName(); $actionName = $this->getActionName(); $d = Core_Mvc_Router::resourceEncode($controllerName,$actionName); $d[self::controllerAccessor] = $controllerName; $d[self::actionAccessor] = $actionName; if (!empty($args)) $d = array_merge($args, $d); $this->_request = array_merge($this->_request, $d); $_GET = array_merge($_GET, $d); $_REQUEST = array_merge($_REQUEST, $d); unset($d); return $this; } /** * 从请求中分析 Controller、Action 名字,然后执行指定的 Action 方法 * * @return mixed */ function dispatching() { $controllerName = $this->getControllerName(); $actionName = $this->getActionName(); // 执行之前要进行Acl权限校验 if (Core_Event::isRegistered(Core_Mvc_EventId::dispatching_aclcheck)){ $success = false; try { // 获取当前用户信息 $currentUser = Core_Event::trigger(Core_Mvc_EventId::dispatching_aclcheck_guser); $args = Core_Mvc_Acl::combindAclCheckParams($controllerName, $actionName, $currentUser); $success = Core_Event::trigger(Core_Mvc_EventId::dispatching_aclcheck,$args); } catch(Core_Mvc_Dispatcher_Exception_CheckFailed $ex){ $this->_dispatchingFailedHandler->denyAccess($ex); } catch(Exception $ex){ $this->_dispatchingFailedHandler->otherCause($ex); } if (!$success) return; } return $this->_executeAction($controllerName, $actionName, $this->getControllerClass($controllerName)); } /** * 返回 请求分发失败时的 错误处理器类名 * * @return String */ abstract protected function getDispatchingFailedClass(); /** * 执行指定的 Action 方法 * * @param string $controllerName * @param string $actionName * @param string $controllerClass * * @return mixed */ protected function _executeAction($controllerName, $actionName, $controllerClass) { try { // 确定动作方法名 $actionMethod = Core_Mvc_Dispatcher::actionMethodPrefix . ucfirst($actionName); // 载入控制对应的类定义 try { Core_Autoloader::loadClass($controllerClass,true); } catch (Core_Exception_ExpectedClass $ex){ throw new Core_Mvc_Dispatcher_Exception_MissingController(ucfirst($controllerName), $actionName, $this->_request,$ex->className,$actionMethod,$ex->classFile); } // 构造控制器对象 $controller = new $controllerClass($this, $controllerName); // 检测 action 方法 if (!method_exists($controller, $actionMethod)){ throw new Core_Mvc_Dispatcher_Exception_MissingAction(ucfirst($controllerName),$actionName, $this->_request,$controllerClass,$actionMethod,Core_Autoloader::getClassFile($controllerClass,true)); } // 调用 _beforeExecute() 方法 if (method_exists($controller, '_beforeExecute')) { $controller->_beforeExecute($actionMethod); } // 执行 action 方法 $ret = $controller->{$actionMethod}(); // 调用 _afterExecute() 方法 if (method_exists($controller, '_afterExecute')) { $controller->_afterExecute($actionMethod); } return $ret; } catch(Core_Mvc_Dispatcher_Exception_MissingController $ex){ $this->_dispatchingFailedHandler->missingController($ex); } catch(Core_Mvc_Dispatcher_Exception_MissingAction $ex){ $this->_dispatchingFailedHandler->missingAction($ex); } catch(Exception $ex){ $this->_dispatchingFailedHandler->otherCause($ex); } } /** * 从请求中取得 Controller 名字 * * 如果没有指定 Controller 名字,则返回默认的 Controller 名字。 * * @return string */ function getControllerName() { $controllerName = preg_replace('/[^a-z0-9_]+/i', '', $this->_request[Core_Mvc_Dispatcher::controllerAccessor]); if ($controllerName == '') { $controllerName = Core_Mvc_Dispatcher::defaultController; } return $controllerName; } /** * 设置要访问的控制器名字 * * @param string $controllerName */ function setControllerName($controllerName) { $this->_request[Core_Mvc_Dispatcher::controllerAccessor] = $controllerName; } /** * 从请求中取得 Action 名字 * * 如果没有指定 Action 名字,则返回默认 Action 名字。 * * @return string */ function getActionName() { $actionName = preg_replace('/[^a-z0-9]+/i', '', $this->_request[Core_Mvc_Dispatcher::actionAccessor]); if ($actionName == '') { $actionName = Core_Mvc_Dispatcher::defaultAction; } return $actionName; } /** * 设置要访问的动作名字 * * @param string $actionName */ function setActionName($actionName) { $this->_request[Core_Mvc_Dispatcher::actionAccessor] = $actionName; } /** * 返回指定控制器对应的类名称前缀 * * @return string */ abstract protected function getControllerClassPrefix(); /** * 返回指定控制器对应的类名称 * * @param string $controllerName * * @return string */ protected function getControllerClass($controllerName) { return $this->getControllerClassPrefix() . ucfirst($controllerName); } }
<?php /** * Core_Mvc_Web_Dispatcher 分析 HTTP 请求,并转发到合适的 Controller 对象处理 * */ class Core_Mvc_Web_Dispatcher extends Core_Mvc_Dispatcher { /** * @return Core_Mvc_Web_Dispatcher */ static function getInstance(){ static $it = NULL; if ($it && $it instanceof Core_Mvc_Web_Dispatcher) return $it; $it = new self($_GET); return $it; } protected function getDispatchingFailedClass(){ return Core_App::ini('mvc/web/dispatcher/dispatchingFailedClass','Core_Mvc_Web_Dispatcher_FailedHandler'); } protected function getControllerClassPrefix(){ return Core_App::ini('mvc/web/dispatcher/controllerClassPrefix','Core_Controller_'); } /** * Web 应用默认的异常处理例程 * * @param Exception $ex */ static function defaultExceptionHandler($ex){ defined('CORE_MVC_WEB_EXCEPTIONHANDLER_VIEWDIR') || define('CORE_MVC_WEB_EXCEPTIONHANDLER_VIEWDIR',COREPATH . '/views/errors'); Core_App::writeLog($ex->getMessage(),null,'exception'); $expath = str_ireplace('_','/',strtolower( get_class($ex)) ); $template = CORE_MVC_WEB_EXCEPTIONHANDLER_VIEWDIR . "/{$expath}.php"; if (!file_exists($template)) { $template = CORE_MVC_WEB_EXCEPTIONHANDLER_VIEWDIR . "/exception.php"; } include($template); exit; } } /** * 请求分发失败时被调用的控制器 * * App 作用域下 可以覆盖此类的方法 * */ class Core_Mvc_Web_Dispatcher_FailedHandler implements Core_Mvc_Dispatcher_FailedHandler { function denyAccess(Core_Mvc_Dispatcher_Exception_CheckFailed $ex){throw $ex;} function missingController(Core_Mvc_Dispatcher_Exception_MissingController $ex){throw $ex;} function missingAction(Core_Mvc_Dispatcher_Exception_MissingAction $ex){throw $ex;} function otherCause(Exception $ex){throw $ex;} }
启动文件
<?php require COREPATH.'/bootstrap.php'; // --- 指定类自动加载机制 /** * 定位pkg 命名空间中的类文件路径 * * @param string $class_name * @return string */ function pkg_locate_class($class_name){ if (!preg_match('/^Pkg_/i',$class_name)) return false; $_ = preg_replace('/^Pkg_/i','',$class_name); if (empty($_)) return false; $_ = Core_AppUtils::normalize(strtolower($_),'_'); return PKGPATH . '/' . implode('/',$_) . '.php'; } /** * 定位app库中的类文件路径 * * @param string $class_name * @return string */ function app_locate_class($class_name){ if (!preg_match('/^App_/i',$class_name)) return false; $_ = preg_replace('/^App_/i','',$class_name); if (empty($_)) return false; $_ = Core_AppUtils::normalize(strtolower($_),'_'); return APPPATH . '/classes/' . implode('/',$_) . '.php'; } Core_Autoloader::addLocateRule('app_locate_class'); Core_Autoloader::addLocateRule('pkg_locate_class'); // 加载配置信息并设置 日志,缓存,DB 等缺省对象 Core_App::loadConfig( require(APPPATH . '/config/system.php') ); // 记录用户代理 Core_App::writeLog($_SERVER['HTTP_USER_AGENT'],'HTTP_USER_AGENT'); // 执行 Mvc_Web 分发器 Core_App::replaceIni( require(APPPATH . '/config/mvc.php') ); Core_Autoloader::loadClass('Core_Mvc_Web_Dispatcher',TRUE); // 设置异常处理 set_exception_handler(Core_App::ini('mvc/web/exceptionHandler','Core_Mvc_Web_Dispatcher::defaultExceptionHandler')); // 进行HTTP请求 映射 Core_Mvc_Web_Router::getInstance()->mappingResource($_GET); /** * TODO: 设置请求分发前置过滤器: 诸如: 权限验证 之类的 * 此处采用全局事件机制来实现 过滤器的功能 */ // 注册Acl检查事件 //Core_Event::register(Core_Mvc_EventId::dispatching_aclcheck, // new Core_Event_PrototypeChain(array('App_Event_Acl_CheckEvent'))); //// 注册Acl检查时依赖的获取当前登录用户信息的事件 //Core_Event::register(Core_Mvc_EventId::dispatching_aclcheck_guser, // new Core_Event_PrototypeChain(array('App_Event_Acl_LoginUser'))); // 以及进行分发操作 $response = Core_Mvc_Web_Dispatcher::getInstance()->dispatching(); if ($response) echo $response; |
|
返回顶楼 | |