哪些网站有项目开发源码-苏州互联印象科技有限公司
Website Home
软件开发工程师编程如果在项目截止日,你的程序不能跑起来或达不到客户的要求,你就拿不到钱百度一下就知道ThinkPHP是一个开源的PHP框架,是为了简化企业级应用开发和敏捷WEB应用开发而诞生的。最早诞生于2006年初,原名FCS,2007年元旦正式更名为ThinkPHP,并且遵循Apache2开源协议发布。早期的思想架构来源于Struts,后来经过不断改进和完善,同时也借鉴了国外很多优秀的框架和模式,使用面向对象的开发结构和MVC模式,融合了Struts的Action和DAO思想和JSP的TagLib(标签库)、RoR的ORM映射和ActiveRecord模式,封装了CURD和一些常用操作,单一入口模式等,在模版引擎、缓存机制、认证机制和扩展性方面均有独特的表现课程播放地址:该老师讲课风格:讲课亲切自然,朴实无华,没有矫揉造作,也不刻意渲染,而是娓娓而谈,细细道来,师生之间在一种平等、协作、和谐的气氛下,进行默默的情感交流,将对知识的渴求和探索融于简朴、真实的教学情景之中,学生在静静的思考、默默的首肯中获得知识本视频中较为难点是ThinkPHP-RBAC介绍了:RBAC是Role-BasedAccessControl的首字母,译成中文即基于角色的权限访问控制,说白了也就是用户通过角色与权限进行关联[其架构灵感来源于操作系统的GBAC(GROUP-BasedAccessControl)的权限管理控制]。简单的来说,一个用户可以拥有若干角色,每一个角色拥有若干权限。这样,就构造成“用户-角色-权限”的授权模型。在这种模型中,用户与角色之间,角色与权限之间,一般者是多对多的关系。在许多的实际应用中,系统不只是需要用户完成简单的注册,还需要对不同级别的用户对不同资源的访问具有不同的操作权限。且在企业开发中,权限管理系统也成了重复开发效率最高的一个模块之一。而在多套系统中,对应的权限管理只能满足自身系统的管理需要,无论是在数据库设计、权限访问和权限管理机制方式上都可能不同,这种不致性也就存在如下的憋端:维护多套系统,重复造轮子,时间没用在刀刃上用户管理、组织机制等数据重复维护,数据的完整性、一致性很难得到保障权限系统设计不同,概念理解不同,及相应技术差异,系统之间集成存在问题,单点登录难度大,也复杂的企业系统带来困难RBAC是基于不断实践之后,提出的一个比较成熟的访问控制方案。实践表明,采用基于RBAC模型的权限管理系统具有以下优势:由于角色、权限之间的变化比角色、用户关系之间的变化相对要慢得多,减小了授权管理的复杂性,降低管理开销;而且能够灵活地支持应用系统的安全策略,并对应用系统的变化有很大的伸缩性;在操作上,权限分配直观、容易理解,便于使用;分级权限适合分层的用户级形式;重用性强。ThinkPHP中RBAC实现体系ThinkPHP中RBAC基于Java的Spring的Acegi安全系统作为参考原型,并做了相应的简化处理,以适应当前的ThinkPHP结构,提供一个多层、可定制的安全体系来为应用开发提供安全控制。安全体系中主要有以下几部分:安全拦截器认证管理器决策访问管理器运行身份管理器安全拦截器安全拦截器就好比一道道门,在系统的安全防护系统中可能存在很多不同的安全控制环节,一旦某个环节你未通过安全体系认证,那么安全拦截器就会实施拦截。认证管理器防护体系的第一道门就是认证管理器,认证管理器负责决定你是谁,一般它通过验证你的主体(通常是一个用户名)和你的凭证(通常是一个密码),或者更多的资料来做到。更简单的说,认证管理器验证你的身份是否在安全防护体系授权范围之内。访问决策管理虽然通过了认证管理器的身份验证,但是并不代表你可以在系统里面肆意妄为,因为你还需要通过访问决策管理这道门。访问决策管理器对用户进行授权,通过考虑你的身份认证信息和与受保护资源关联的安全属性决定是是否可以进入系统的某个模块,和进行某项操作。例如,安全规则规定只有主管才允许访问某个模块,而你并没有被授予主管权限,那么安全拦截器会拦截你的访问操作。决策访问管理器不能单独运行,必须首先依赖认证管理器进行身份确认,因此,在加载访问决策过滤器的时候已经包含了认证管理器和决策访问管理器。为了满足应用的不同需要,ThinkPHP在进行访问决策管理的时候采用两种模式:登录模式和即时模式。登录模式,系统在用户登录的时候读取改用户所具备的授权信息到Session,下次不再重新获取授权信息。也就是说即使管理员对该用户进行了权限修改,用户也必须在下次登录后才能生效。即时模式就是为了解决上面的问题,在每次访问系统的模块或者操作时候,进行即使验证该用户是否具有该模块和操作的授权,从更高程度上保障了系统的安全。运行身份管理器运行身份管理器的用处在大多数应用系统中是有限的,例如某个操作和模块需要多个身份的安全需求,运行身份管理器可以用另一个身份替换你目前的身份,从而允许你访问应用系统内部更深处的受保护对象。这一层安全体系目前的RBAC中尚未实现。ThinkPHP中RBAC认证流程对应上面的安全体系,ThinkPHP的RBAC认证的过程大致如下:判断当前模块的当前操作是否需要认证如果需要认证并且尚未登录,跳到认证网关,如果已经登录执行5通过委托认证进行用户身份认证获取用户的决策访问列表判断当前用户是否具有访问权限权限管理的具体实现过程RBAC相关的数据库介绍在ThinkPHP完整包,包含了RBAC处理类RBAC.class.php文件,位于Extend/Library/ORG/Util。打开该文件,其中就包含了使用RBAC必备的4张表,SQL语句如下(复制后请替换表前缀):CREATETABLEIFNOTEXISTS`ly_access`(`role_id`smallint(6)unsignedNOTNULL,`node_id`smallint(6)unsignedNOTNULL,`level`tinyint(1)NOTNULL,`module`varchar(50)DEFAULTNULL,KEY`groupId`(`role_id`),KEY`nodeId`(`node_id`))ENGINE=MyISAMDEFAULTCHARSET=utf8;CREATETABLEIFNOTEXISTS`ly_node`(`id`smallint(6)unsignedNOTNULLAUTO_INCREMENT,`name`varchar(20)NOTNULL,`title`varchar(50)DEFAULTNULL,`status`tinyint(1)DEFAULT'0'`remark`varchar(255)DEFAULTNULL,`sort`smallint(6)unsignedDEFAULTNULL,`pid`smallint(6)unsignedNOTNULL,`level`tinyint(1)unsignedNOTNULL,PRIMARYKEY(`id`),KEY`level`(`level`),KEY`pid`(`pid`),KEY`status`(`status`),KEY`name`(`name`))ENGINE=MyISAMDEFAULTCHARSET=utf8;CREATETABLEIFNOTEXISTS`ly_role`(`id`smallint(6)unsignedNOTNULLAUTO_INCREMENT,`name`varchar(20)NOTNULL,`pid`smallint(6)DEFAULTNULL,`status`tinyint(1)unsignedDEFAULTNULL,`remark`varchar(255)DEFAULTNULL,PRIMARYKEY(`id`),KEY`pid`(`pid`),KEY`status`(`status`))ENGINE=MyISAMDEFAULTCHARSET=utf8;CREATETABLEIFNOTEXISTS`ly_role_user`(`role_id`mediumint(9)unsignedDEFAULTNULL,`user_id`char(32)DEFAULTNULL,KEY`group_id`(`role_id`),KEY`user_id`(`user_id`))ENGINE=MyISAMDEFAULTCHARSET=utf8;这里还给大家推荐了源码资源的下载:素材文档源码图解模板本文实例讲述了Laravel5.1onSAE环境开发方法。分享给大家供大家参考,具体如下:Laravel-简洁、优雅的PHP开发框架,为WEB艺术家创造的PHP框架,如今正式移植到SAE环境。由于Laravel5.1相比于Laravel4有很多的改动,不仅以目录结构更加清晰,而且功能也更丰富。但是Laravel官方还是没有原生支持SAE环境(估计永远不会支持),所以我就做了一个移植版本,可以很优雅的切换本地和SAE环境。由于SAE的特殊性,那么这几个核心问题就必须要解决#1putenv()函数禁用#2模板编译#3缓存类#4日志处理#5Session类#6服务提供者缓存#1putenv()函数禁用Laravel5.1使用了这个putenv()函数来向当前的环境中动态添加变量,但是很遗憾的是SAE的PHPRuntime禁用了该函数,所以只能使用折中的方法来实现。当初本来想Hook掉该实现,后来觉得没必要,这个函数在Laravel5.1中主要是为了使用.env配置文件来统一团队的配置。所以我是直接禁用了该功能,在vendor/vlucas/phpdotenv/src/Dotenv.php的86行左右,直接注释掉该函数,然后把所有的配置信息都写到config文件夹的相应配置文件中。虽然解决了该函数被禁用的问题,但是实现的不够优雅,希望有大神可以给出更加优雅的实现。#2模板编译该问题主要还是因为SAE的本地环境写入被禁止,所以我使用了Wrapper来把编译后的模板文件写入到Storage。本来是打算写到KVDB中,但是会出现一些奇奇怪怪问题,原因不明。在configview.php文件中修改:$compiled=[paths=>[realpath(base_path(resources/views)),],compiled=>realpath(storage_path(framework/views)),];if(SAE){$compiled[compiled]=saestor://.SAE_STORAGE./compiled;}return$compiled;注意要在相应的Storage中建立compiled文件夹。#3缓存类Laravel5.1没有直接提供SAE可用的Memcache缓存驱动,这个解决比较简单,直接写一个服务提供者注册到app.php即可,然后在configcache.php中注册,具体实现看项目源码#4日志处理这也是一个比较棘手的问题,由于Laravel5.1的日志处理已经不是和4一样使用服务提供者,而且直接注入到启动器中,这就使得我们只能覆写原生ConfigureLogging启动类,而官方也没有给出如何覆写和在哪里覆写,所以我这边的解决方案是判断当前环境为SAE后直接重写Http内核中的一个启动器属性,核心代码:namespaceIlluminateCloudSAE;useAppHttpKernelasDefaultKernel;classKernelextendsDefaultKernel{/***Thebootstrapclassesfortheapplication.**@vararray*/protected$bootstrappers=[IlluminateFoundationBootstrapDetectEnvironment,IlluminateFoundationBootstrapLoadConfiguration,IlluminateCloudSAELogConfigureLogging,IlluminateFoundationBootstrapHandleExceptions,IlluminateFoundationBootstrapRegisterFacades,IlluminateFoundationBootstrapRegisterProviders,IlluminateFoundationBootstrapBootProviders,];}这样还不行,还必须重写日志的部分实现classWriterextendsIlluminateLogWriter{protectedfunctionuseSaeLog($level=debug){$level=$this->parseLevel($level);$this->monolog->pushHandler($handler=newSaeLogHandler($level));$handler->setFormatter($this->getDefaultFormatter());}publicfunctionuseFiles($path,$level=debug){if(SAE){return$this->useSaeLog($level);}parent:useFiles($path,$level);}publicfunctionuseDailyFiles($path,$days=0,$level=debug){if(SAE){return$this->useSaeLog($level);}parent:useDailyFiles($path,$days,$level);}}#5Session类Laravel5.1的session依旧是本地写的问题,参考了Laravel4的移植,使用了memcache作为session的实现,具体可以结合缓存部分来处理#6服务提供者缓存在应用程序的启动过程中,laravel会在bootstrap/cache/services.json生成服务提供者的缓存,为了加快下次访问的速度,依旧是本地写的问题,解决方案很简单,使用Storage的Wrapper即可以上这些问题解决后,差不多就算成功了。最后修改下bootstrapapp.php来实现本地与SAE环境的优雅切换,主要是判断环境然后生成SAE专有应用实例和注入相应的Http内核。/*|--------------------------------------------------------------------------|CreateTheApplication|--------------------------------------------------------------------------||ThefirstthingwewilldoiscreateanewLaravelapplicationinstance|whichservesastheglueforallthecomponentsofLaravel,andis|theIoCcontainerforthesystembindingallofthevariousparts.|*/define(SAE,true);define(SAE_STORAGE,laravel);if(SAE){$app=newIlluminateCloudSAEApplication(realpath(__DIR__././));$app->singleton(IlluminateContractsHttpKernel:class,IlluminateCloudSAEKernel:class);}else{$app=newIlluminateFoundationApplication(realpath(__DIR__././));$app->singleton(IlluminateContractsHttpKernel:class,AppHttpKernel:class);}/*|--------------------------------------------------------------------------|BindImportantInterfaces|--------------------------------------------------------------------------||Next,weneedtobindsomeimportantinterfacesintothecontainerso|wewillbeabletoresolvethemwhenneeded.Thekernelsservethe|incomingrequeststothisapplicationfromboththewebandCLI.|*/$app->singleton(IlluminateContractsConsoleKernel:class,AppConsoleKernel:class);$app->singleton(IlluminateContractsDebugExceptionHandler:class,AppExceptionsHandler:class);/*|--------------------------------------------------------------------------|ReturnTheApplication|--------------------------------------------------------------------------||Thisscriptreturnstheapplicationinstance.Theinstanceisgivento|thecallingscriptsowecanseparatethebuildingoftheinstances|fromtheactualrunningoftheapplicationandsendingresponses.|*/return$app;这里解释下为什么要在bootstrapapp.php中来定义是否为SAE环境,原因很明确了,就是要注入相应的应用程序实例和Http实例,然后再这里也定义一下Storage然后就是configapp.php的相关配置,根据环境判断来注入相应的服务提供者if(SAE){$removeProviders=[IlluminateCacheCacheServiceProvider:class,IlluminateSessionSessionServiceProvider:class,];for($i=0;$i<count($app[providers]);$i++){if(in_array($app[providers][$i],$removeProviders)){unset($app[providers][$i]);}}$app[providers]=array_merge($app[providers],[IlluminateCloudSAECacheSaeCacheServiceProvider:class,IlluminateCloudSAESessionSessionServiceProvider:class,IlluminateCloudSAEStorageStorageServiceProvider:class,IlluminateCloudSAESegmentSegmentServiceProvider:class,]);$app[aliases][Storage]=IlluminateCloudSAEStorageStorage:class;$app[aliases][Segment]=IlluminateCloudSAESegmentSegment:class;}最后再说说SAE专有应用程序实例和Http实例与原生的差别,主要还是本地写的问题。原生的会在应用程序启动时候生成路由、配置、服务提供者、模板编译的相关文件,以此来提升加载速度。但是到了SAE就不行了,所以重写了Application类的部分与路径相关的方法,来把这些文件生成到Storage中,而Http专有内核则是处理启动器中的日志类。具体代码就不贴出来,可以看看项目。再给一个SAE可以使用的rewritehandle:-rewrite:if(path~^/$)gotopublic/index.php-rewrite:if(!is_dir()&&!is_file()&&path~^(.*)$)gotopublic/index.php/$1总结整个移植过程还算是很顺利,得益于Laravel的拓展性与SAE的便利.不过在对于putenv()函数和日志处理的解决方法上,还是实现的不够优雅,希望能有人给出更有优雅的实现方案。然后其他的SAE服务比如分词、邮件、队列等,则可以使用服务提供者自动加载,这个就不多说了。项目github地址:软件点击此处本站下载。