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 "465136132568d7b316e8cec31569aa67af7ce8b6d4e472a55d78c0fbdf22401b" => :high_sierra sha256 "14da8ba8723bb18884271e0e4c3df9e4be5317529bcaa0cf3c7ef30191c2cdc6" => :sierra sha256 "13bd8badd9da31e5f71fa29d624b47a1a18b693f37aa419c552bbe7ba497e4c2" => :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 # icu4c 61.1 compatability ENV.append "CPPFLAGS", "-DU_USING_ICU_NAMESPACE=1" 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