今天晚上开始在新浪云计算平台SAE部署我的第一个应用,一个图床。程序代码据说是提取自isaid的,整个代码和教程来自于这里,其实这个算比较简单的一个组件吧,我只做了小部分修改。教程里面有的我就不重复了,下面说一下教程里面没有的。
开始使用使用新浪云计算的sdk上传代码的时候,需要先在新浪云计算应用中心,进入你的应用里面的 “应用管理-代码管理” 里面创建一个版本,版本只能是一个正整数,默认为1。创建版本之后,在本地sdk中选择“下载全部Apps”,然后对应到你的本地app目录(默认为你sdk目录下面的apps文件夹,例如我这里是E:saeSAE_SDK_Windows_1.0.5apps)里面应该有与应用名一致的文件夹,再往里面就是一个应用各版本的文件夹,以版本号为目录名。在这个以版本号数字为名的文件夹里面你需要放置code文件夹,code文件夹里面才是需要上传的代码,对应web的根目录。我一开始犯的错误就是没有使用创建代码版本,直接手工建立各级文件夹(例如我这里是E:saeSAE_SDK_Windows_1.0.5appshorsley1code,horsley是应用名)。
版本等问题解决之后我在sdk中点击“更新上传”按钮得到了一个error,说不存在config.yaml。有玩过用过Google App Engine (GAE)做各种应用(各种代理程序……##¥%&%¥)的童鞋应该大概知道这是一个配置文件,包含应用的版本号,应用名等信息。这个文件存放位置应该是在版本号文件夹下,与code文件夹处于同一层(例如我这里是E:saeSAE_SDK_Windows_1.0.5appshorsley1config.yaml)。没有这个文件夹怎么办呢?我们可以在sdk工具右上方文件列表窗口右键,选择菜单里面的“编辑config.yaml”,这时候他就会提示你“APP的config.yaml文件不存在,是否创建一个?”当我们点击“是”按钮之后它就会帮我们创建一个config.yaml文件,并且里面已经有需要的默认的内容了。这个文件创建好之后我们再上传代码就不会有问题了。
上传完之后按照教程进行安装初始化,安装成功之后开始登陆,登陆以后却出现了错误
SAE_Warning: Cannot modify header information – headers already sent by (output started at /data1/www/htdocs/605/horsley/1/config.php:1) in manager/index.phpon line 53
这个问题有点眼熟,以前折腾暨南人新闻网wordpress的时候遇到过。大概情况就是php里面用到了header函数,header函数要求必须在有任何实际浏览器输出之前调用,下面是php手册里面的对header函数的原文提示:
Remember that header() must be called before any actual output is sent, either by normal HTML tags, blank lines in a file, or from PHP. It is a very common error to read code with include(), or require(), functions, or another file access function, and have spaces or empty lines that are output before header() is called. The same problem exists when using a single PHP/HTML file.
很多时候我们都需要调用header函数发送location的http都控制浏览器跳转,而这个错误的发生原因很多时候是我们不经意制造了一些浏览器输出。按照sae警告的内容找到这个config.php,在有行号显示的编辑器里面(例如我在使用的notepad++)打开这个文件可以很明显的看到文件末尾有一个空行,这就是问题所在。我们写c++代码的时候,使用例如我们作业要求的c-free5+mingw编译环境,如果文件末尾没有一个空行,将会产生一个编译器警告。php和c是同一系列的语言风格,不知道是不是这个原因所以在这个php文件末尾多了一个引起问题的空行。
突然想起一个东西,当我们为sae上边的应用创建一个新代码版本之后,sae默认写入一个index.php,内容如下
<?php echo '<strong>Welcome to SAE!</strong>';
一开始我看了觉得很奇怪,怎么这个php标签没有闭合啊?简单google一下发现,其实这种写法有一个主要的好处:避免 ?> 后面的不可见字符(多余的空格、换行符)等破坏页面显示,也不会导致 Header already sent 这样的警告信息。因为没有结束标签 ?> 所以就算文件末尾有多余空行,用于没有php结束标签,这个空行就属于php解析的范围而不是直接的浏览器输出。在php代码范围里面,空行不产生输出也不影响代码。不过,我们也应该注意这个用法只能是在文件末尾的php结束标签?>才可以这样省略,其他地方我们还是需要使用结束标签的,例如php嵌入html。
凡事多思考,多问个为什么,这样才能有进步。