论坛首页 编程语言技术论坛

PHP程序员是否应该使用自己写的框架

浏览 18756 次
精华帖 (0) :: 良好帖 (5) :: 新手帖 (0) :: 隐藏帖 (5)
作者 正文
   发表时间:2012-05-02  
achun 写道
我认为如果项目有一定规模,一定要有自己核心稳定的技术leader,
那技术方案就应该由leader决定.
当然,如果让我选方案,我是不会用目前常见的框架的,不是因为人家的框架不好,而恰恰是因为维护成本高的问题,
个人感觉流行的PHP框架都有一个共性,那就是庞大,那些不庞大的都不能流行.
PHP之下不应该出现庞大框架,因为这违背了PHP的精神,PHP追求的就是简单快速.
但是一个不庞大的框架,相信有一定水准的PHPer都可以写出来.
就算你用框架也不能避免混合着SQL语句的代码,因为php本来就是这样的,
PHP的一个特有现象:
框架要流行就要全面大.
但是大项目用这样的框架不见得合适,因为你项目够大,就要招聘足够实力的技术,但是有这样实力的技术都会按照项目需求快速构建一个定制的框架.
至于你说的,后续招的人不合适的问题,那和你用啥框架无关的.
对于php招人,如果不能快速上手一个陌生的框架,那就不是个合适的人选.
而对于一个php框架,如果不能让人上手,那也不是好的框架.



深有同感 ........
0 请登录后投票
   发表时间:2012-05-02  
个人感觉 主要还是在于 模块切分上面 至于底层框架 我觉得并不是 项目进度慢的 主要问题

..........

0 请登录后投票
   发表时间:2012-05-02  
有自己开发的框架可以用,前提是必须简单易学,比大框架要简单n倍,半天能学会才行。
如果自己开发的框架比cakephp还复杂,能赶上zf,那不如使用大的框架
1 请登录后投票
   发表时间:2012-05-02  
想我没做的一个模块出来就能上线一个模块,没有花多少个月。
什么项目4个月才做出一半啊
0 请登录后投票
   发表时间:2012-05-04  
个人觉得 thinkphp 比较好用。

如果需要绝对的性能,建议考虑一下 http://code.google.com/p/slightphp/

zend framework当类库。
0 请登录后投票
   发表时间:2012-05-04  
再NB的人没用对地方也没用,就好比一个JAVA大牛去做c#一样
0 请登录后投票
   发表时间:2012-05-04  
xiaokang1582830 写道
再NB的人没用对地方也没用,就好比一个JAVA大牛去做c#一样

是认为PHP不应该有框架吗?还是认为PHP程序员不应该在生产环境使用自己写的框架?
0 请登录后投票
   发表时间:2012-05-04  
 
  如果你在一个研究机构,有足够的时间,可以自己写框架。
  如果你在一个商业机构。别人怎么写,你也怎么写。你写过的代码就会成为你将来的“框架”。哪怕是
paste & copy.
  框架无非是一些规范和约束,从来没有“银弹”。没有积累相当的coding经验,企图通过寻找框架
来提高效率是舍本求末。
   对于web开发,我一直有点困惑。微软、IBM等巨头在商业开发中都有各自成熟的开发框架,只是对于
单兵或两三人开发又不适用。于是大家又陷入了开源项目或“重新发明轮子”的困惑中。
   其实从java 的 web开发中可见一斑。无论是胖客户还是瘦客户。无论是web 2.0 抑或是 组件式的 JSF。
沸沸扬扬折腾一大圈,还是最初那个 基于 MVC的STRUTS最好用。为什么? web这种无状态连接方式应用,还是
采用MVC最靠谱。
   总之,我想要么就啥框架别用。要么就采用大公司的框架。
   当然,如果你是开公司的,从卖服务的角度作长远打算,那是非得有个框架不可了。

   一年多不做技术了,不当之处,还望指正。
0 请登录后投票
   发表时间:2012-05-05  
eserver220 写道
 
  如果你在一个研究机构,有足够的时间,可以自己写框架。
  如果你在一个商业机构。别人怎么写,你也怎么写。你写过的代码就会成为你将来的“框架”。哪怕是
paste & copy.
  框架无非是一些规范和约束,从来没有“银弹”。没有积累相当的coding经验,企图通过寻找框架
来提高效率是舍本求末。
   对于web开发,我一直有点困惑。微软、IBM等巨头在商业开发中都有各自成熟的开发框架,只是对于
单兵或两三人开发又不适用。于是大家又陷入了开源项目或“重新发明轮子”的困惑中。
   其实从java 的 web开发中可见一斑。无论是胖客户还是瘦客户。无论是web 2.0 抑或是 组件式的 JSF。
沸沸扬扬折腾一大圈,还是最初那个 基于 MVC的STRUTS最好用。为什么? web这种无状态连接方式应用,还是
采用MVC最靠谱。
   总之,我想要么就啥框架别用。要么就采用大公司的框架。
   当然,如果你是开公司的,从卖服务的角度作长远打算,那是非得有个框架不可了。

   一年多不做技术了,不当之处,还望指正。

框架引入规范和约束正是项目开发的根本需求,这不算是舍本求末,因为很多时候这些规范和约束是必须的,无论是从安全还是持续性上都需要的,简单的举个例子,数据库操作有很多安全和效率的问题,如果不采用框架或者数据库封装类,那么散乱的代码一旦出问题,你就去挨个扒拉吧,但是有了框架和数据库封装类那问题解决起来就快速的多.
因此作为一个开发者研究和选择框架是不可少的一个方向.当然怎么样才算合适的框架这个每个人都有自己的不同意见.
0 请登录后投票
   发表时间:2012-05-05   最后修改:2012-05-05

我这边现在用了我写的IWP框架 这个过程不经历不知道 痛并快乐中...

 

慢慢走吧...路 大框架又需要自定义 ... 这也不是个轻松的活 .....

 

如果 出名的框架真那么好 为什么大家还要自己写...

 

像 ZF CAKEPHP 这些很强 .... 但如果不深入 定制似乎很难...

 

比如 zf 的 控制器 这块 一般的人根本看不懂里面的实现机制........

 

而作为技术指导者,你又必须去告知他们实现机制,而不是给个文档就能了事,出了问题就让他上网找...这都是不现实的

而一旦被深入提问,你就悲催了.... 难不成你告诉他 就这么用,一知半解??? 那下次这个问题 是否又会重复被提问

 

 

像 lz 提出的 任务延迟案例... 我个人觉得绝对不是框架的问题,作为框架实现者 之所以实现框架 就是为了节省开发时间,提高开发效率的

 

在项目开发中,延迟的可能性很多,例如:

 

1. 需求是否总跳... 这点大部分的人都在为此死B的无眠....

2. 开发人员是否到位... 分工是否明确...

3. 模块拆分,功能设计,任务分配 是否.....

4. 你招的那个大拿是否有带队的经验.....

 

php 开发框架 说白了 就是 MVC + db封装类(例如 啥子 orm 的)

 

复杂度与java相比 应该是 0.01 ....

 

至于 现在出现问题,我觉得不应该 推卸全部责任到 这位大拿的框架上.... 而是整个团队需要静下心来 总结前期工作的失误过程

 

找出可以修改的地方,予以改正....  互相指责能解决问题么????

 

对于 lz , 如果可能 可以把那位大拿写的框架 给我看看.. 我可以帮忙分析下 复杂度........

补全文档对我而言不是个轻松的活,幸好框架足够小,容易调教 ... 例如 mvc 实现...

<?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;
0 请登录后投票
论坛首页 编程语言技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics