- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章Laravel 5.1 on SAE环境开发教程【附项目demo源码】由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
本文实例讲述了Laravel 5.1 on SAE环境开发方法。分享给大家供大家参考,具体如下:
Laravel-简洁、优雅的PHP开发框架,为 WEB 艺术家创造的 PHP 框架,如今正式移植到SAE环境.
由于Laravel 5.1相比于Laravel 4有很多的改动,不仅以目录结构更加清晰,而且功能也更丰富。但是Laravel官方还是没有原生支持SAE环境(估计永远不会支持),所以我就做了一个移植版本,可以很优雅的切换本地和SAE环境.
由于SAE的特殊性,那么这几个核心问题就必须要解决 。
#1 putenv()函数禁用 #2 模板编译 #3 缓存类 #4 日志处理 #5 Session类 #6 服务提供者缓存 。
#1 putenv()函数禁用 。
Laravel 5.1使用了这个putenv()函数来向当前的环境中动态添加变量,但是很遗憾的是SAE的PHPRuntime禁用了该函数,所以只能使用折中的方法来实现。当初本来想Hook掉该实现,后来觉得没必要,这个函数在Laravel 5.1中主要是为了使用.env配置文件来统一团队的配置。所以我是直接禁用了该功能,在vendor/vlucas/phpdotenv/src/Dotenv.php的86行左右,直接注释掉该函数,然后把所有的配置信息都写到config文件夹的相应配置文件中。虽然解决了该函数被禁用的问题,但是实现的不够优雅,希望有大神可以给出更加优雅的实现.
#2 模板编译 。
该问题主要还是因为SAE的本地环境写入被禁止,所以我使用了Wrapper来把编译后的模板文件写入到Storage。本来是打算写到KVDB中,但是会出现一些奇奇怪怪问题,原因不明.
在config\view.php文件中修改
1
2
3
4
5
6
7
8
9
10
|
$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 缓存类 。
Laravel 5.1没有直接提供SAE可用的Memcache缓存驱动,这个解决比较简单,直接写一个服务提供者注册到app.php即可,然后在config\cache.php中注册,具体实现看项目源码 。
#4 日志处理 。
这也是一个比较棘手的问题,由于Laravel 5.1的日志处理已经不是和4一样使用服务提供者,而且直接注入到启动器中,这就使得我们只能覆写原生ConfigureLogging启动类,而官方也没有给出如何覆写和在哪里覆写,所以我这边的解决方案是判断当前环境为SAE后直接重写Http内核中的一个启动器属性,核心代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
namespace
Illuminate\Cloud\SAE;
use
App\Http\Kernel
as
DefaultKernel;
class
Kernel
extends
DefaultKernel{
/**
* The bootstrap classes for the application.
*
* @var array
*/
protected
$bootstrappers
= [
'Illuminate\Foundation\Bootstrap\DetectEnvironment'
,
'Illuminate\Foundation\Bootstrap\LoadConfiguration'
,
'Illuminate\Cloud\SAE\Log\ConfigureLogging'
,
'Illuminate\Foundation\Bootstrap\HandleExceptions'
,
'Illuminate\Foundation\Bootstrap\RegisterFacades'
,
'Illuminate\Foundation\Bootstrap\RegisterProviders'
,
'Illuminate\Foundation\Bootstrap\BootProviders'
,
];
}
|
这样还不行,还必须重写日志的部分实现 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
class
Writer
extends
IlluminateLogWriter {
protected
function
useSaeLog(
$level
=
'debug'
){
$level
=
$this
->parseLevel(
$level
);
$this
->monolog->pushHandler(
$handler
=
new
SaeLogHandler(
$level
));
$handler
->setFormatter(
$this
->getDefaultFormatter());
}
public
function
useFiles(
$path
,
$level
=
'debug'
){
if
(SAE) {
return
$this
->useSaeLog(
$level
);
}
parent::useFiles(
$path
,
$level
);
}
public
function
useDailyFiles(
$path
,
$days
= 0,
$level
=
'debug'
){
if
(SAE) {
return
$this
->useSaeLog(
$level
);
}
parent::useDailyFiles(
$path
,
$days
,
$level
);
}
}
|
#5 Session类 。
Laravel5.1的session依旧是本地写的问题,参考了Laravel4的移植,使用了memcache作为session的实现,具体可以结合缓存部分来处理 。
#6 服务提供者缓存 。
在应用程序的启动过程中,laravel会在bootstrap/cache/services.json生成服务提供者的缓存,为了加快下次访问的速度,依旧是本地写的问题,解决方案很简单,使用Storage的Wrapper即可 以上这些问题解决后,差不多就算成功了。最后修改下bootstrap\app.php来实现本地与SAE环境的优雅切换,主要是判断环境然后生成SAE专有应用实例和注入相应的Http内核.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
|
/*
|--------------------------------------------------------------------------
| Create The Application
|--------------------------------------------------------------------------
|
| The first thing we will do is create a new Laravel application instance
| which serves as the "glue" for all the components of Laravel, and is
| the IoC container for the system binding all of the various parts.
|
*/
define(
'SAE'
,true);
define(
'SAE_STORAGE'
,
'laravel'
);
if
(SAE){
$app
=
new
Illuminate\Cloud\SAE\Application(
realpath
(__DIR__.
'/../'
)
);
$app
->singleton(
Illuminate\Contracts\Http\Kernel::
class
,
Illuminate\Cloud\SAE\Kernel::
class
);
}
else
{
$app
=
new
Illuminate\Foundation\Application(
realpath
(__DIR__.
'/../'
)
);
$app
->singleton(
Illuminate\Contracts\Http\Kernel::
class
,
App\Http\Kernel::
class
);
}
/*
|--------------------------------------------------------------------------
| Bind Important Interfaces
|--------------------------------------------------------------------------
|
| Next, we need to bind some important interfaces into the container so
| we will be able to resolve them when needed. The kernels serve the
| incoming requests to this application from both the web and CLI.
|
*/
$app
->singleton(
Illuminate\Contracts\Console\Kernel::
class
,
App\Console\Kernel::
class
);
$app
->singleton(
Illuminate\Contracts\Debug\ExceptionHandler::
class
,
App\Exceptions\Handler::
class
);
/*
|--------------------------------------------------------------------------
| Return The Application
|--------------------------------------------------------------------------
|
| This script returns the application instance. The instance is given to
| the calling script so we can separate the building of the instances
| from the actual running of the application and sending responses.
|
*/
return
$app
;
|
这里解释下为什么要在bootstrap\app.php中来定义是否为SAE环境,原因很明确了,就是要注入相应的应用程序实例和Http实例,然后再这里也定义一下Storage 。
然后就是config\app.php的相关配置,根据环境判断来注入相应的服务提供者 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
if
(SAE){
$removeProviders
= [
Illuminate\Cache\CacheServiceProvider::
class
,
Illuminate\Session\SessionServiceProvider::
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'
],[
Illuminate\Cloud\SAE\Cache\SaeCacheServiceProvider::
class
,
Illuminate\Cloud\SAE\Session\SessionServiceProvider::
class
,
Illuminate\Cloud\SAE\Storage\StorageServiceProvider::
class
,
Illuminate\Cloud\SAE\Segment\SegmentServiceProvider::
class
,
]);
$app
[
'aliases'
][
'Storage'
] = Illuminate\Cloud\SAE\Storage\Storage::
class
;
$app
[
'aliases'
][
'Segment'
] = Illuminate\Cloud\SAE\Segment\Segment::
class
;
}
|
最后再说说SAE专有应用程序实例和Http实例与原生的差别,主要还是本地写的问题。原生的会在应用程序启动时候生成路由、配置、服务提供者、模板编译的相关文件,以此来提升加载速度。但是到了SAE就不行了,所以重写了Application类的部分与路径相关的方法,来把这些文件生成到Storage中,而Http专有内核则是处理启动器中的日志类。具体代码就不贴出来,可以看看项目.
再给一个SAE可以使用的rewrite 。
1
2
3
|
handle:
- rewrite:
if
(path ~
"^/$"
) goto
"public/index.php"
- rewrite:
if
(!is_dir() && !is_file() && path~
"^(.*)$"
) goto
"public/index.php/$1"
|
总结 。
整个移植过程还算是很顺利,得益于Laravel的拓展性与SAE的便利.不过在对于putenv()函数和日志处理的解决方法上,还是实现的不够优雅,希望能有人给出更有优雅的实现方案。然后其他的SAE服务比如分词、邮件、队列等,则可以使用服务提供者自动加载,这个就不多说了.
项目github地址: https://github.com/wh469012917/laravel5-on-sae 。
希望本文所述对大家基于Laravel框架的PHP程序设计有所帮助.
最后此篇关于Laravel 5.1 on SAE环境开发教程【附项目demo源码】的文章就讲到这里了,如果你想了解更多关于Laravel 5.1 on SAE环境开发教程【附项目demo源码】的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
ACO.Visualization项目 本项目演示蚁群算法求解旅行商问题的可视化过程,包括路径上的信息素浓度、蚁群的运动过程等。项目相关的代码:https://github.com/anycad/A
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 7 年前。
我需要用Sql数据库制作并包含的PHP票务系统源码用户客户端和管理员。我需要个人 CMS 的这个来源。谢谢你帮助我。 最佳答案 我在不同的情况下使用了 osticket。 这里: http://ost
我的场景:我想在日志文件中写入发生异常的部分代码(例如,发生异常的行前 5 行和行后 5 行 - 或者至少是该方法的所有代码)。 我的想法是用 C# 代码反编译 pdb 文件,并从该反编译文件中找到一
RocketMQ设定了延迟级别可以让消息延迟消费,延迟消息会使用 SCHEDULE_TOPIC_XXXX 这个主题,每个延迟等级对应一个消息队列,并且与普通消息一样,会保存每个消息队列的消费进度
先附上Hystrix源码图 在微服务架构中,根据业务来拆分成一个个的服务,服务与服务之间可以相互调用(RPC),在Spring Cloud可以用RestTemplate+Ribbon和
此篇博客学习的api如标题,分别是: current_url 获取当前页面的url; page_source 获取当前页面的源码; title 获取当前页面的titl
? 1 2
1、前言 作为一个数据库爱好者,自己动手写过简单的sql解析器以及存储引擎,但感觉还是不够过瘾。<<事务处理-概念与技术>>诚然讲的非常透彻,但只能提纲挈领,不能让你
gory"> 目录 运行时信号量机制 semaphore 前言 作用是什么 几个主要的方法 如何实现
自己写的一个评论系统源码分享给大家,包括有表情,还有评论机制。用户名是随机的 针对某一篇文章进行评论 function subcomment() {
一、概述 StringBuilder是一个可变的字符串序列,这个类被设计去兼容StringBuffer类的API,但不保证线程安全性,是StringBuffer单线程情况下的一个替代实现。在可能的情
一、概述 System是用的非常多的一个final类。它不能被实例化。System类提供了标准的输入输出和错误输出流;访问外部定义的属性和环境变量;加载文件和库的方法;以及高效的拷贝数组中一部分元素
在JDK中,String的使用频率和被研究的程度都非常高,所以接下来我只说一些比较重要的内容。 一、String类的概述 String类的声明如下: public final class Str
一、概述 Class的实例代表着正在运行的Java应用程序的类和接口。枚举是一种类,而直接是一种接口。每一个数组也属于一个类,这个类b被反射为具有相同元素类型和维数的所有数组共享的类对象。八大基本树
一、概述 Compiler这个类被用于支持Java到本地代码编译器和相关服务。在设计上,这个类啥也不做,他充当JIT编译器实现的占位符。 放JVM虚拟机首次启动时,他确定系统属性java.comp
一、概述 StringBuffer是一个线程安全的、可变的字符序列,跟String类似,但它能被修改。StringBuffer在多线程环境下可以很安全地被使用,因为它的方法都是通过synchroni
一、概述 Enum是所有Jav中枚举类的基类。详细的介绍在Java语言规范中有说明。 值得注意的是,java.util.EnumSet和java.util.EnumMap是Enum的两个高效实现,
一、概述 此线程指的是执行程序中的线程。 Java虚拟机允许应用程序同时执行多个执行线程。 每个线程都有优先权。 具有较高优先级的线程优先于优先级较低的线程执行。 每个线程可能也可能不会被标记为守
一、抽象类Number 类继承关系 这里面的原子类、BigDecimal后面都会详细介绍。 属性和抽象方法 二、概述 所有的属性,最小-128,最大127,SIZE和BYTES代码比
我是一名优秀的程序员,十分优秀!