如何在CircleCI中缓存通过PECL安装的PHP扩展?
The issue with your current cache setup is that you're only storing the compiled mongodb.so file, but PECL still re-downloads the extension source because you're not caching the PECL download cache directory (where source packages are stored) and you're not checking if the extension is already installed before running pecl install.
Here's the fix to properly cache the extension and skip redundant downloads/compilation:
Step 1: Restore Cache Before Installation
First, add a step to restore any existing cache before attempting to install the extension. Including PHP version in the cache key ensures you don't mix extensions built for incompatible PHP versions:
- restore_cache: keys: # Specific key with PHP version, script checksum, and branch - pecl-mongodb-v1-{{ php -r "echo PHP_VERSION;" }}-{{ checksum "scripts/pecl-extensions.sh" }}-{{ .Branch }} # Fallback key if branch-specific cache doesn't exist - pecl-mongodb-v1-{{ php -r "echo PHP_VERSION;" }}-{{ checksum "scripts/pecl-extensions.sh" }}
Step 2: Install Extension Only If Missing
Instead of running pecl install every time, check if the extension is already loaded first. This skips the installation entirely if the cache was restored successfully:
- run: | # Check if mongodb extension is already enabled if ! php -m | grep -q mongodb; then sudo pecl install mongodb # Add the extension to php.ini only if it's not already present if ! grep -q "extension=mongodb.so" /usr/local/etc/php/php.ini; then echo -e "extension=mongodb.so" | sudo tee -a /usr/local/etc/php/php.ini > /dev/null fi fi
Step 3: Save the Correct Directories to Cache
You need to cache two critical directories to avoid re-downloading and re-compiling:
- PECL's download cache: Stores source packages so PECL doesn't need to fetch them from the internet.
- Compiled extensions directory: Stores the pre-built
mongodb.sofile.
Update your save_cache step to include these paths:
- save_cache: key: pecl-mongodb-v1-{{ php -r "echo PHP_VERSION;" }}-{{ checksum "scripts/pecl-extensions.sh" }}-{{ .Branch }} paths: # Default PECL download cache directory (verify with `pecl config get cache_dir` if unsure) - /tmp/pear/cache/ # Directory containing the compiled mongodb.so (adjust the suffix to match your PHP version) - /usr/local/lib/php/extensions/no-debug-non-zts-20160303/ # Optional: Cache php.ini if you don't modify it elsewhere in your pipeline # - /usr/local/etc/php/php.ini
Why This Works
/tmp/pear/cache/: PECL caches downloaded source packages here. Saving this directory skips the slow network download step entirely on subsequent builds.- The extensions directory: Storing the pre-compiled
mongodb.someans you don't have to re-run the resource-heavy compilation process. - The versioned cache key ensures your cache stays relevant if you update your PHP version or extension installation script.
Quick Tip
If you're unsure about the exact path to your extensions directory, run php -i | grep extension_dir in your CircleCI job to get the correct path for your environment.
内容的提问来源于stack exchange,提问作者hoonzis

