class Php < Formula
desc "General-purpose scripting language"
homepage "https://php.net/"
url "https://php.net/get/php-7.2.4.tar.xz/from/this/mirror"
sha256 "7916b1bd148ddfd46d7f8f9a517d4b09cd8a8ad9248734e7c8dd91ef17057a88"
bottle do
sha256 "31b351285ef21d5aa9bf3ba951c515f63d6b4c7257faceeb8066ffa00a195ec9" => :high_sierra
sha256 "e571305130a3393eb90c6c6c9df3e75da0faa7a1ca36523e296b8fd20f1b389b" => :sierra
sha256 "620f0c2c3b057fc2929d72b8beec2ca79fbf7505c22dc88c642da13123db142f" => :el_capitan
end
depends_on "httpd" => [:build, :test]
depends_on "pkg-config" => :build
depends_on "apr"
depends_on "apr-util"
depends_on "argon2"
depends_on "aspell"
depends_on "curl" if MacOS.version < :lion
depends_on "freetds"
depends_on "freetype"
depends_on "gettext"
depends_on "glib"
depends_on "gmp"
depends_on "icu4c"
depends_on "jpeg"
depends_on "libpng"
depends_on "libpq"
depends_on "libsodium"
depends_on "libzip"
depends_on "openssl"
depends_on "pcre"
depends_on "unixodbc"
depends_on "webp"
needs :cxx11
def install
# Ensure that libxml2 will be detected correctly in older MacOS
if MacOS.version == :el_capitan || MacOS.version == :sierra
ENV["SDKROOT"] = MacOS.sdk_path
end
inreplace "configure" do |s|
s.gsub! "APACHE_THREADED_MPM=`$APXS_HTTPD -V | grep 'threaded:.*yes'`",
"APACHE_THREADED_MPM="
s.gsub! "APXS_LIBEXECDIR='$(INSTALL_ROOT)'`$APXS -q LIBEXECDIR`",
"APXS_LIBEXECDIR='$(INSTALL_ROOT)#{lib}/httpd/modules'"
s.gsub! "-z `$APXS -q SYSCONFDIR`",
"-z ''"
end
# Update error message in apache sapi to better explain the requirements
# of using Apache http in combination with php if the non-compatible MPM
# has been selected. Homebrew has chosen not to support being able to
# compile a thread safe version of PHP and therefore it is not
# possible to recompile as suggested in the original message
inreplace "sapi/apache2handler/sapi_apache2.c",
"You need to recompile PHP.",
"Homebrew PHP does not support a thread-safe php binary. "\
"To use the PHP apache sapi please change "\
"your httpd config to use the prefork MPM"
inreplace "sapi/fpm/php-fpm.conf.in", ";daemonize = yes", "daemonize = no"
# Required due to icu4c dependency
ENV.cxx11
config_path = etc/"php/#{php_version}"
# Prevent homebrew from harcoding path to sed shim in phpize script
ENV["lt_cv_path_SED"] = "sed"
args = %W[
--prefix=#{prefix}
--localstatedir=#{var}
--sysconfdir=#{config_path}
--with-config-file-path=#{config_path}
--with-config-file-scan-dir=#{config_path}/conf.d
--enable-bcmath
--enable-calendar
--enable-dba
--enable-dtrace
--enable-exif
--enable-ftp
--enable-fpm
--enable-intl
--enable-mbregex
--enable-mbstring
--enable-mysqlnd
--enable-opcache-file
--enable-pcntl
--enable-phpdbg
--enable-phpdbg-webhelper
--enable-shmop
--enable-soap
--enable-sockets
--enable-sysvmsg
--enable-sysvsem
--enable-sysvshm
--enable-wddx
--enable-zip
--with-apxs2=#{Formula["httpd"].opt_bin}/apxs
--with-bz2
--with-fpm-user=_www
--with-fpm-group=_www
--with-freetype-dir=#{Formula["freetype"].opt_prefix}
--with-gd
--with-gettext=#{Formula["gettext"].opt_prefix}
--with-gmp=#{Formula["gmp"].opt_prefix}
--with-icu-dir=#{Formula["icu4c"].opt_prefix}
--with-jpeg-dir=#{Formula["jpeg"].opt_prefix}
--with-kerberos
--with-layout=GNU
--with-ldap
--with-ldap-sasl
--with-libedit
--with-libzip
--with-mhash
--with-mysql-sock=/tmp/mysql.sock
--with-mysqli=mysqlnd
--with-ndbm
--with-openssl=#{Formula["openssl"].opt_prefix}
--with-password-argon2=#{Formula["argon2"].opt_prefix}
--with-pdo-dblib=#{Formula["freetds"].opt_prefix}
--with-pdo-mysql=mysqlnd
--with-pdo-odbc=unixODBC,#{Formula["unixodbc"].opt_prefix}
--with-pdo-pgsql=#{Formula["libpq"].opt_prefix}
--with-pgsql=#{Formula["libpq"].opt_prefix}
--with-pic
--with-png-dir=#{Formula["libpng"].opt_prefix}
--with-pspell=#{Formula["aspell"].opt_prefix}
--with-sodium=#{Formula["libsodium"].opt_prefix}
--with-unixODBC=#{Formula["unixodbc"].opt_prefix}
--with-webp-dir=#{Formula["webp"].opt_prefix}
--with-xmlrpc
--with-xsl
--with-zlib
]
if MacOS.version < :lion
args << "--with-curl=#{Formula["curl"].opt_prefix}"
else
args << "--with-curl"
end
system "./configure", *args
system "make"
system "make", "install"
# Allow pecl to install outside of Cellar
extension_dir = Utils.popen_read("#{bin}/php-config --extension-dir").chomp
orig_ext_dir = File.basename(extension_dir)
inreplace bin/"php-config", lib/"php", prefix/"pecl"
inreplace "php.ini-development", "; extension_dir = \"./\"",
"extension_dir = \"#{HOMEBREW_PREFIX}/lib/php/pecl/#{orig_ext_dir}\""
config_files = {
"php.ini-development" => "php.ini",
"sapi/fpm/php-fpm.conf" => "php-fpm.conf",
"sapi/fpm/www.conf" => "php-fpm.d/www.conf",
}
config_files.each_value do |dst|
dst_default = config_path/"#{dst}.default"
rm dst_default if dst_default.exist?
end
config_path.install config_files
unless (var/"log/php-fpm.log").exist?
(var/"log").mkpath
touch var/"log/php-fpm.log"
end
end
def caveats
<<~EOS
To enable PHP in Apache add the following to httpd.conf and restart Apache:
LoadModule php7_module #{opt_lib}/httpd/modules/libphp7.so
SetHandler application/x-httpd-php
Finally, check DirectoryIndex includes index.php
DirectoryIndex index.php index.html
The php.ini and php-fpm.ini file can be found in:
#{etc}/php/#{php_version}/
EOS
end
def post_install
pear_prefix = share/"pear"
pear_files = %W[
#{pear_prefix}/.depdblock
#{pear_prefix}/.filemap
#{pear_prefix}/.depdb
#{pear_prefix}/.lock
]
%W[
#{pear_prefix}/.channels
#{pear_prefix}/.channels/.alias
].each do |f|
chmod 0755, f
pear_files.concat(Dir["#{f}/*"])
end
chmod 0644, pear_files
# Custom location for extensions installed via pecl
pecl_path = HOMEBREW_PREFIX/"lib/php/pecl"
ln_s pecl_path, prefix/"pecl" unless (prefix/"pecl").exist?
extension_dir = Utils.popen_read("#{bin}/php-config --extension-dir").chomp
php_basename = File.basename(extension_dir)
php_ext_dir = opt_prefix/"lib/php"/php_basename
# fix pear config to install outside cellar
pear_path = HOMEBREW_PREFIX/"share/pear"
{
"php_ini" => etc/"php/#{php_version}/php.ini",
"php_dir" => pear_path,
"doc_dir" => pear_path/"doc",
"ext_dir" => pecl_path/php_basename,
"bin_dir" => opt_bin,
"data_dir" => pear_path/"data",
"cfg_dir" => pear_path/"cfg",
"www_dir" => pear_path/"htdocs",
"man_dir" => HOMEBREW_PREFIX/"share/man",
"test_dir" => pear_path/"test",
"php_bin" => opt_bin/"php",
}.each do |key, value|
value.mkpath if key =~ /(? "php-fpm"
def plist; <<~EOS
KeepAlive
Label
#{plist_name}
ProgramArguments
#{opt_sbin}/php-fpm
--nodaemonize
RunAtLoad
WorkingDirectory
#{var}
StandardErrorPath
#{var}/log/php-fpm.log
EOS
end
test do
assert_match /^Zend OPcache$/, shell_output("#{bin}/php -i"), "Zend OPCache extension not loaded"
system "#{sbin}/php-fpm", "-t"
system "#{bin}/phpdbg", "-V"
system "#{bin}/php-cgi", "-m"
# Prevent SNMP extension to be added
assert_no_match /^snmp$/, shell_output("#{bin}/php -m"), "SNMP extension doesn't work reliably with Homebrew on High Sierra"
begin
require "socket"
server = TCPServer.new(0)
port = server.addr[1]
server_fpm = TCPServer.new(0)
port_fpm = server_fpm.addr[1]
server.close
server_fpm.close
expected_output = /^Hello world!$/
(testpath/"index.php").write <<~EOS
SetHandler application/x-httpd-php
EOS
(testpath/"fpm.conf").write <<~EOS
[global]
daemonize=no
[www]
listen = 127.0.0.1:#{port_fpm}
pm = dynamic
pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3
EOS
(testpath/"httpd-fpm.conf").write <<~EOS
#{main_config}
LoadModule mpm_event_module lib/httpd/modules/mod_mpm_event.so
LoadModule proxy_module lib/httpd/modules/mod_proxy.so
LoadModule proxy_fcgi_module lib/httpd/modules/mod_proxy_fcgi.so
SetHandler "proxy:fcgi://127.0.0.1:#{port_fpm}"
EOS
pid = fork do
exec Formula["httpd"].opt_bin/"httpd", "-X", "-f", "#{testpath}/httpd.conf"
end
sleep 3
assert_match expected_output, shell_output("curl -s 127.0.0.1:#{port}")
Process.kill("TERM", pid)
Process.wait(pid)
fpm_pid = fork do
exec sbin/"php-fpm", "-y", "fpm.conf"
end
pid = fork do
exec Formula["httpd"].opt_bin/"httpd", "-X", "-f", "#{testpath}/httpd-fpm.conf"
end
sleep 3
assert_match expected_output, shell_output("curl -s 127.0.0.1:#{port}")
ensure
if pid
Process.kill("TERM", pid)
Process.wait(pid)
end
if fpm_pid
Process.kill("TERM", fpm_pid)
Process.wait(fpm_pid)
end
end
end
end