Ramblings on technology with a dash of social commentary
RSS icon Email icon Home icon
  • Extending Apple Apache & PHP with Homebrew

    Posted on November 18th, 2014 PHP Guru No comments

    Quick start

    I recently got a new Macbook Pro (Mavericks) and decided to use the bundled Apache 2.2.6 and PHP 5.4.30.

    All you have to do is uncomment the PHP extension:

    LoadModule php5_module libexec/apache2/libphp5.so

    in /private/etc/apache2/httpd.conf and start Apache:

    sudo apachectl start

    This had me up and running in no time, but after a few days I realized I needed some additional extensions, including MySQL, Mcrypt, Mongo and Redis.

    Brew to the rescue

    There’s no better package manager for Mac OS X than Homebrew (except possibly Macports). So after installing Homebrew:

    ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

    I set off to install some additional software and PHP-native extensions:

    brew install redis
    ...
    redis-server start
    brew install php54-redis
    ==> Installing php54-redis from homebrew/homebrew-php
    ==> Downloading https://github.com/nicolasff/phpredis/archive/2.2.5.tar.gz
    ######################################################################## 100.0%
    ==> PHP_AUTOCONF="/usr/local/opt/autoconf/bin/autoconf" PHP_AUTOHEADER="/usr/local/opt/autoconf/bin/autoheader" /usr/local/Cellar/php54
    ==> ./configure --prefix=/usr/local/Cellar/php54-redis/2.2.5 --with-php-config=/usr/local/Cellar/php54/5.4.33/bin/php-config
    ==> make
    ==> Caveats
    To finish installing redis for PHP 5.4:
    * /usr/local/etc/php/5.4/conf.d/ext-redis.ini was created,
    do not forget to remove it upon extension removal.
    * Validate installation via one of the following methods:
    *
    * Using PHP from a webserver:
    * - Restart your webserver.
    * - Write a PHP page that calls "phpinfo();"
    * - Load it in a browser and look for the info on the redis module.
    * - If you see it, you have been successful!
    *
    * Using PHP from the command line:
    * - Run "php -i" (command-line "phpinfo()")
    * - Look for the info on the redis module.
    * - If you see it, you have been successful!
    ==> Summary
    (beer) /usr/local/Cellar/php54-redis/2.2.5: 3 files, 216K, built in 9 seconds

    Okay, now I should be able to use Redis commands (PHPRedis) in PHP, right?

    Wrong! Whoops:

    sudo apachectl restart

    How about now?

    Nope!

    php -i | grep redis

    Nope, phpinfo() doesn’t show it.

    php -m | grep redis

    Nada; no Redis extension. Rat’s why didn’t that work?

    Solution

    Let’s look back at the output from the brew php54-redis installer. This part in particular:

    * /usr/local/etc/php/5.4/conf.d/ext-redis.ini was created,
    

    So, what gives? That seems pretty legit. At least for an Apache & PHP config installed by Homebrew.

    Oh, right, we didn’t do that.

    Here’s the problem: That’s not where Apple’s default PHP build is configured to load extra parsed ini files from.

    That path, by default, is:

    /Library/Server/Web/Config/php/

    To make the situation even more confusing, that path doesn’t even exist! And, it doesn’t even exist in any config file! It’s actually supplied as an argument (by someone at Apple who worked on the Mac OS X Mavericks Rom supplied to the Macbook Pro factory) when building the PHP binary:

    Configure Command => ... '--with-config-file-scan-dir=/Library/Server/Web/Config/php' ...

    which means we can’t even alter it without re-compiling PHP. Not that we couldn’t, but we don’t need to. Here’s why…

    Symlinks for fun and profit

    All we need to do is get the ini files created by homebrew installers to be loaded by the built-in Apache/PHP that ships with Apple and we are good to go.

    Create this lame, un-changeable non-existent directory tree (-p is recursive; go figure):

    sudo mkdir -p /Library/Server/Web/Config/php

    Next, symlink in there the redis.ini

    sudo ln -s /usr/local/etc/php/5.4/conf.d/ext-redis.ini /Library/Server/Web/Config/php/redis.ini

    Finally, restart Apache

    sudo apachectl restart

    Did that work?

    php -m | grep redis
    redis

    Yep, I take that as a good sign.

    All future installs of PHP extensions can be sudo symlinked into this same config-file-scan-dir and we’re good to go.

  • Top 10 Redis Resources Online

    Posted on February 4th, 2012 phpguru 2 comments

    Chances are you’ve heard of Memcache. Tons of websites use it to speed up page load times. I often say that Redis is like Memcache on steroids. You may not have heard of Redis, but if you’re using Memcache or APC, you should see how Redis could improve what you’re already doing. If you’re not using Memcache or APC yet, don’t bother – I urge you to take a look at Redis for a bunch of reasons.

    First, Memcache is a key-value store only. You set a string value under a string key, and that’s it. With Redis, on the other hand, you have the luxury of several different types of data storage, including keys and values, but Redis also supports hashes, lists, sets and sorted sets.

    An example to help explain why this is such a huge improvement. Say you have a big array of data, such as the kind that can come back from a web service request, like a parsed XML file or JSON packet. With Memcache, to store this in memory you have to serialize the data, often base64 encode the data, and then store it on the way in, and then to get a portion of the data back out again, you have to get the whole string, base64 decode it, deserialize it and then you can read from it. These extra steps needlessly chew up compute cycles.

    With the same data object stored in a Redis Hash, for example, you can have instant access to the data stored in any key of the hash, you don’t have to grab the whole thing, deserialize it and all that mess. Just a single line of code, and boom, there’s your data. Much more elegant.

    Another key reason Redis is superior to Memcache is that when you ask Memcache to store something, it’s in memory and that’s it. If your server goes down and you have to reboot, you have to repopulate your Memcache data over again. If your app has gotten huge, and your cache is huge, this can not only take awhile but puts a huge strain on your database server during this so-called “cache warmup” period. Unlike Memcache, Redis actually stores a copy of its data to a file on disk in the background, so if you stop and start your Redis server, it reloads everything automatically. It does this mind-blowingly fast, too, like millions of keys in seconds.

    Finally, Redis supports master-slave configurations that you can use to build high-availability systems more easily. In the upcoming release (everyone is very eager for) Redis Cluster will support sharding out of the box!

    So, now that you want to dig in and start learning Redis, here are my…

    Top 10 Redis Resources Online

    1. Redis documentation: redis.io/commands
    2. Try Redis Online: try.redis-db.com
    3. Redis-DB Google Group List Archives: groups.google.com/group/redis-db
    4. Antirez (Redis developer Salvatore Sanfilippo’s) blog: antirez.com
    5. Recent blog posts about Redis: RSS Feed
    6. Q&A: stackoverflow.com/questions/tagged/redis
    7. The Little Redis Book – Just released openmymind.net/2012/1/23/The-Little-Redis-Book
    8. Slides from Redis Tutorial simonwillison.net/static/2010/redis-tutorial
    9. A Collection of Redis Use Cases www.paperplanes.de/2010/2/16/a_collection_of_redis_use_cases
    10. My GitHub Page. Chock full of Redis-related project forks. github.com/phpguru
    11. Bonus: Here’s a slideshow for a Redis 101 talk I gave if you’re interested.
    Notes
    You may be wondering about NoSQL and where Redis fits into this discussion. When people bring up NoSQL, I tend to think of MongoDB. Unlike Memcached and Redis, MongoDB is a general purpose document/object (think JSON) store that (strangely enough) allows you to use some SQL-like commands to retrieve subsets of your data. I think of Redis as a data structure server. You don’t use SQL to talk to Redis, so I guess it could be considered along with other NoSQL solutions. You can compare Redis to MongoDB by going to try.mongodb.org/