在 Mac 上搭建 owncloud 环境
前言
没想到在Mac上搭建PHP开发环境会有这么多坑,手动编译真是坑到吐血;果然还是包管理器才是王道,不过经过此次折腾,确实是时候学习一些docker的用法了;
TL;DR
- 
利用
homebrew分别安装php,mysql和nginx;1
2
3brew install php
brew install mysql
brew install nginx - 
启动服务:
1
2
3brew services start php
brew services start mysql
brew services start nginx - 
下载对应版本的
owncloud的安装包,解压后放到本地服务器路径下; - 
设置
nginx的服务器配置文件[1];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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108upstream php-handler {
server 127.0.0.1:9000; # 本地php服务器默认地址
#server unix:/var/run/php5-fpm.sock;
}
server {
listen 80; # 要监听的本地端口
server_name ***; # 服务器访问域名
# Add headers to serve security related headers
# Before enabling Strict-Transport-Security headers please read into this topic first.
#add_header Strict-Transport-Security "max-age=15552000; includeSubDomains";
add_header X-Content-Type-Options nosniff;
add_header X-Frame-Options "SAMEORIGIN";
add_header X-XSS-Protection "1; mode=block";
add_header X-Robots-Tag none;
add_header X-Download-Options noopen;
add_header X-Permitted-Cross-Domain-Policies none;
# Path to the root of your installation
root /data/domains/cloud; # owncloud解压后部署的本地路径
location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}
# The following 2 rules are only needed for the user_webfinger app.
# Uncomment it if you're planning to use this app.
#rewrite ^/.well-known/host-meta /public.php?service=host-meta last;
#rewrite ^/.well-known/host-meta.json /public.php?service=host-meta-json last;
location = /.well-known/carddav {
return 301 $scheme://$host/remote.php/dav;
}
location = /.well-known/caldav {
return 301 $scheme://$host/remote.php/dav;
}
location ^~ /.well-known/acme-challenge { }
# set max upload size
client_max_body_size 512M;
fastcgi_buffers 64 4K;
# Disable gzip to avoid the removal of the ETag header
gzip off;
# Uncomment if your server is build with the ngx_pagespeed module
# This module is currently not supported.
#pagespeed off;
error_page 403 /core/templates/403.php;
error_page 404 /core/templates/404.php;
location / {
rewrite ^ /index.php$uri;
}
location ~ ^/(?:build|tests|config|lib|3rdparty|templates|data)/ {
return 404;
}
location ~ ^/(?:\.|autotest|occ|issue|indie|db_|console) {
return 404;
}
location ~ ^/(?:index|remote|public|cron|core/ajax/update|status|ocs/v[12]|updater/.+|ocs-provider/.+|core/templates/40[34])\.php(?:$|/) {
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
#fastcgi_param HTTPS on;
fastcgi_param modHeadersAvailable true; #Avoid sending the security headers twice
fastcgi_param front_controller_active true;
fastcgi_pass php-handler;
fastcgi_intercept_errors on;
fastcgi_request_buffering off; #Available since NGINX 1.7.11
}
location ~ ^/(?:updater|ocs-provider)(?:$|/) {
try_files $uri $uri/ =404;
index index.php;
}
# Adding the cache control header for js and css files
# Make sure it is BELOW the PHP block
location ~* \.(?:css|js)$ {
try_files $uri /index.php$uri$is_args$args;
add_header Cache-Control "max-age=15778463";
# Add headers to serve security related headers (It is intended to have those duplicated to the ones above)
# Before enabling Strict-Transport-Security headers please read into this topic first.
#add_header Strict-Transport-Security "max-age=15552000; includeSubDomains";
add_header X-Content-Type-Options nosniff;
add_header X-Frame-Options "SAMEORIGIN";
add_header X-XSS-Protection "1; mode=block";
add_header X-Robots-Tag none;
add_header X-Download-Options noopen;
add_header X-Permitted-Cross-Domain-Policies none;
# Optional: Don't log access to assets
access_log off;
}
location ~* \.(?:svg|gif|png|html|ttf|woff|ico|jpg|jpeg)$ {
try_files $uri /index.php$uri$is_args$args;
# Optional: Don't log access to other assets
access_log off;
}
} - 
重启
nginx服务;1
brew services restart nginx
 - 
访问配置的本地服务地址(域名+端口),然后按照页面指示初始化
owncloud应用设置(管理员账号和数据库配置)即可;需要注意的是MySQL数据库地址需要带上端口号,默认端口为3306; 
注:owncloud不同的版本对于PHP版本会有不同的要求,以10.11.1版本为例,该版本不兼容7.3及以上版本的PHP;
Homebrew加速镜像
由于homebrew安装包的服务器默认都在国外,因此下载包时速度较慢,对于体积大的包来说经常会出现超时而导致安装失败的问题;解决这种问题的套路那自然就是使用国内镜像,这里推荐使用中科大的镜像:
上面两个镜像建议都替换,上述页面都有详细的替换和还原说明;
nginx配置文件
nginx安装成功后,通过nginx -h命令可以看到默认配置文件的路径:

打开默认配置文件可以看到,默认servers文件夹(默认配置文件的同级目录)下的所有配置文件都会被自动解析,因此一般都在该文件下放入自定义的服务器配置文件;
遇到的坑
由于之前在windows系统上搭建过PHP开发环境,因此不自觉的以为在Mac上也是那么轻松,所以一开始就选了那种流行的PHP集成环境安装包的模式,结果就碰到了很多的坑……
集成环境安装包的问题
在Mac上用集成环境安装包搭建PHP环境的最大问题是:一旦PHP需要额外的扩展模块时,需要自行安装或手动编译;而在Windows系统上往往只需要在php.ini配置文件上将相应模块的注释取消即可,因为默认扩展模块的dll文件都编译好了;
以owncloud10.11.1为例,该应用依赖intl(国际化)扩展模块,而集成环境默认都没有携带这个扩展模块的编译文件(.so),因此需要自行解决;
手动编译可能会遇到的问题
一般来说,PHP扩展模块在Mac上的手动编译流程大如下[2]:
- 
到PECL网站(专门托管
PHP扩展模块源码的仓库)找到对应的扩展模块; - 
然后下载扩展模块相应版本的源码压缩包,进行解压;
 - 
命令行进入源码文件夹下(有
config.m4文件的那级目录),运行:1
phpize
运行成功后,目录下会生成一个
configure文件; - 
接着运行:
1
2# path-to-php为当前使用的PHP安装路径
./configure --with-php-config=path-to-php/bin/php-config - 
然后进行编译:
1
sudo make
 - 
最后将编译好的文件安装到
PHP扩展模块目录中:1
sudo make install
 
理想情况下,经过上面的一番操作,应该是生成对应扩展模块编译产物(.so文件)且安装到目录中的;然而,事实上运行的每个命令都可能会出现各种各样的错误……
icu4c包找不到
在运行./configure命令时,极有可能会出现下面的错误:
1  | configure: error: Unable to detect ICU prefix or no failed. Please verify ICU install prefix and make sure icu-config works.  | 
原因可能是:
- 
没有安装
icu4c包;此时可以通过homebrew来安装解决:1
brew install icu4c
 - 
安装了但是没有暴露到环境变量中;可以尝试使用
homebrew的link命令来解决:1
brew link icu4c
不过有可能会出现警告,但是也提示了如何手动暴露到环境变量中去:

 
ext/standard/php_smart_str.h’ file not found
可能好不容易成功运行了./configure命令后,在执行编译命令时又会出现如下错误:
1  | Fatal error: 'ext/standard/php_smart_str.h' file not found  | 
很明显,php_smart_str.h这个头文件要么是缺失了,要么就是没有正确地暴露在环境变量中;
mysql加密方式不支持
在使用mysql8.0+版本时,其默认账号加密方式变为caching_sha2_password,而很多PHP版本不支持这种加密方式,因此就会出现如下错误:
1  | mysqli_real_connect(): The server requested authentication method unknown to the client [sha256_password]  | 
一般可以采用改写数据库中账号加密方式来解决[3]:
1  | ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '你的密码'  | 
不过上述方式我试了后仍然无效,所以此时可以采用另一种方法,那就是使用mysql官方的Mac安装包来安装mysql,安装过程中可以选择采用mysql5.7的加密方式来兼容现有的PHP;
相关文档
- 在 macOS Catalina 10.15 搭建 PHP 开发环境 | Laravel China 社区:基于
homebrew安装相应的包(php+mysql+linux),强烈推荐 - MySQL :: Download MySQL Community Server: 
mysql的安装包,如果mysql8.0+(通过homebrew安装)的加密方式报错无法解决时,可以使用官方安装包,因为安装时可以选择低版本(mysql5.7)的加密方式; - Mac 系统下安装配置MySQL的方法 - 知乎:通过安装包安装
MySQL需要自己暴露环境变量 - PHP for OS X / macOS as binary package (deprecated):基于
Mac编译了大多数扩展模块的PHP源码,不过目前不再维护了 - php - Fatal error: ‘ext/standard/php_smart_str.h’ file not found - Stack Overflow:自行编译
intl扩展包可能会出现Fatal error: 'ext/standard/php_smart_str.h' file not found的报错; - Installation failed with icu-config error on Mac OS X 10.8 · Issue #21 · phpbrew/phpbrew:编译
intl模块(具体是运行./configure命令时)可能会出现configure: error: Unable to detect ICU prefix or no failed. Please verify ICU install prefix and make sure icu-config works.的报错,原因是环境变量中找不到icu4c包 - phpMyAdmin - 配置文件权限错误,不应任何用户都能修改!_JadePlus的技术博客-CSDN博客:运行
phpmyadmin时可能会出现配置文件权限错误,不应任何用户都能修改!的报错,原因就是phpmyadmin目录权限过高 - MAC 10.15.6系统修改允许安装任何来源后,依然无效问题 - 代码先锋网
 - MxSrvs - MacOS平台的PHP集成开发环境
 - 安裝/激活運行MAMP的PHP「intl」擴展 - 優文庫:一种解决
PHP扩展模块缺失的方法 - mac xampp php安装intl扩展 - 极客分享:一种解决
PHP扩展模块缺失的方法 - 2020年最好用的6个php环境搭建工具推荐
 - mac 下安装使用pear/pecl - 范松伟的文章 - 知乎:也可以借助
pear/pecl来管理PHP扩展模块 
Nginx+ownCloud+PHP+MySQL搭建私有云 - 云+社区 - 腾讯云:
owncloud默认带了Apache服务器的一些配置(.htaccess文件),使用Nginx作为服务器时,需要转化为相应的规则(.cnf文件),这篇文章就有现成的 ↩︎Mac环境下安装PHP扩展踩坑指南 - Renjie的文章 - 知乎:
PHP扩展模块编译的一般流程 ↩︎mysql 安装了最新版本8.x版本后的报错: the server requested authentication method unknown to the client_youcijibi的博客-CSDN博客:
mysql8.0+版本加密方式错误的解决办法之一 ↩︎