接到个项目,大致是制作一个微信上访问的H5,需要存下用户提交的文字与照片。
前端同事写了个demo,我先在本地搭环境进行测试。
随便拿了几张几百k的图片测试,用了我利用空余时间自己写的简单api模板和文件上传类,十几分钟搞定本地代码。直接上测试服务器。
在测试服务器测试过程中遇到了一系列问题。
- 题:调试过程中,在多次使用file_put_contents输出错误却看不到相应返回。
答:咨询了管理员才了解。原来测试服务器的FTP是有主从的,约10分钟同步一次。
解:由于此测试服不在我们的管理范围内,只好谨慎的上传。毕竟不巧的话,上传后可能要19分钟才能看到结果。
- 题:测试服务器对应的数据库在执行insert和update语句时能够成功运行,而执行select语句时,会报出“1146表不存在”的错误。
答:经过Google查询初步了解情况,推测数据库也是主从架构,然后向数据库管理员进行确认。得知数据库也是主从的架构,10分钟同步一次,但是可能配置出了点问题,主库的表在创建后没有同步到从库里。insert和update语句是直接运行在主库里,所以没有问题,而select语句读的是从库,从而导致1146错误。
解:我们也没有数据库的管理权限,只好等数据库管理员修复。
- 题:所使用的文件上传类是用move_uploaded_file来存储上传的文件。通过获取结果,该函数返回了true,之后的方法也成功运行了文件名及路径也存入了数据库,但是图片却没有在FTP上找到。
答:经过获取服务器端ip以及使用gethostbyname,gethostname等函数获取所请求的服务器在内网的地址等信息。经过分析判断以及向管理员求证,由于FTP服务是不定时切换的,若外网访问的是从服务器,则图片会被存在从服务器里。但是主从同步只会由主向从同步,而不会逆向进行。
解:正式站不是主从的设计,直接写了个demo上正式站进行测试,经测问题无法重现,则略过了该问题。
- 题:我方流程测试完成,将地址发给了几位同事进行测试时,发生了有时候图片上传了,却没有存下图,数据库里也没存入图片信息的问题。
答:经过多次重现,定位到是在单个图片过大的时候,才会发生问题。通过file_put_contents输出$_FILES,得知当单个图片大于3M时,$_FILES会变成空数组。
解:经过查询手册,更改了php.ini中几个参数,重启后问题得到解决。
对上文中提到的一些函数及配置进行说明
- file_put_contents($filename,$data,$flag)
对线上文件进行调试的不二利器,配合var_export($expression,true)能够将数组或对象转化为字符串,便于写入log。
eg.
file_put_contents(‘fl.log‘,var_export($_FILES,true)."\r\n",FILE_APPEND);
- move_uploaded_file($filename,$destination)
一般文件上传类用到的根本都是这个方法,将tmp_name存入给予的文件路径下。注意$destination必须是绝对路径。
eg.
move_uploaded_file($tmp_name, LOCAL_ROOT.$save_path);
- gethostbyname($hostname)
将给予的hostname转换为IPv4地址
eg.
gethostbyname(‘cn.bing.com‘); //202.89.233.103
- gethostname()
此函数会返回当前机器的hostname,对于windows系统的计算机来说也就是“计算机名”。
- php.ini 中 post_max_size 配置项
设置单次post数据的最大值,上传大文件时,该值必须大于upload_max_filesize。通常memory_limit必须大于post_max_size
eg.
post_max_size = 20M
- php.ini 中 upload_max_filesize 配置项
设置上传单个文件的最大值,
eg.
upload_max_filesize = 64M
- get_cfg_var($option)
能够获取PHP配置项值的函数,在服务器不在我方管辖范围内的情况,且不便于过多打扰管理员时,特别管用。
eg.
get_cfg_var(‘upload_max_filesize‘); //64M
总结
- 需要用到的服务器是否特殊的架构之类要提前咨询清楚,知己知彼能够省下很多时间。
- 在本地测试时一定要测试极限情况,假如我在本地测试时,用一个10M的图测一下,也能少很多事情。
- 一拿到任何服务器时,最好能先看一下phpinfo,了解php版本等情况。假如项目里有需要上传等操作,也可以用get_cfg_var先看一下所配置大小够不够。