Install the Package
composer require a9f/fractor-htaccess --dev
Ensure it’s added to your composer.json under require-dev (as it’s a dev dependency).
Register the Processor
In your Fractor service configuration (e.g., config/fractor.php), register the HtaccessFileProcessor under the processors key:
'processors' => [
\A9F\FractorHtaccess\Processor\HtaccessFileProcessor::class,
],
Define a Rule
Create a class implementing a9f\FractorHtaccess\Contract\HtaccessFractorRule and tag it with fractor.htaccess_rule:
namespace App\Rules;
use A9F\FractorHtaccess\Contract\HtaccessFractorRule;
class AddRewriteRule implements HtaccessFractorRule
{
public function process(array $htaccessLines): array
{
return array_merge($htaccessLines, [
'RewriteRule ^old-path$ /new-path [L,R=301]',
]);
}
}
Register the rule in a service provider:
$this->app->tag([AddRewriteRule::class], 'fractor.htaccess_rule');
Run Fractor
Use the Artisan command to process .htaccess files in your project:
php artisan fractor:process
Goal: Add a 301 redirect for a deprecated URL.
php artisan fractor:process to apply changes to all .htaccess files in your project.Line-Level Manipulation
Rules can modify, add, or remove specific lines in .htaccess files. Example:
public function process(array $htaccessLines): array
{
$lines = array_filter($htaccessLines, fn($line) => !str_contains($line, 'DeprecatedRule'));
return array_merge($lines, ['# Replaced by new rule']);
}
Conditional Processing Use rules to conditionally apply changes based on file location or content:
public function process(array $htaccessLines): array
{
if (str_contains($htaccessLines[0], 'WordPress')) {
return array_merge($htaccessLines, [
'RewriteEngine On',
'RewriteRule ^wp-admin$ - [F]',
]);
}
return $htaccessLines;
}
Multi-File Processing
Leverage Fractor’s built-in file discovery to process .htaccess files in:
public/.htaccess).public/subdir/.htaccess).fractor.php).Combine with Other Fractor Packages
Use alongside fractor-php or fractor-js for multi-filetype projects. Example:
'processors' => [
\A9F\FractorPhp\Processor\PhpFileProcessor::class,
\A9F\FractorHtaccess\Processor\HtaccessFileProcessor::class,
],
Custom File Discovery
Extend HtaccessFileProcessor to include/exclude specific files:
protected function getFilesToProcess(): array
{
return array_filter(parent::getFilesToProcess(), fn($file) =>
!str_contains($file, 'vendor') && str_ends_with($file, '.htaccess')
);
}
Dry Runs and Backups
Use Fractor’s --dry-run flag to preview changes:
php artisan fractor:process --dry-run
Enable backups in config/fractor.php:
'backup' => true,
Read-Only Mode
The package is read-only by design (as per the description). To modify .htaccess files, you’ll need to:
file_put_contents in a post-processing hook).Line Order Sensitivity
.htaccess rules often depend on order (e.g., RewriteEngine must come before RewriteRule). Ensure your rules preserve or enforce correct ordering:
public function process(array $htaccessLines): array
{
$rewriteEngineIndex = array_search('RewriteEngine On', $htaccessLines);
if ($rewriteEngineIndex === false) {
array_unshift($htaccessLines, 'RewriteEngine On');
}
return $htaccessLines;
}
Syntax Errors
Invalid .htaccess syntax can break your site. Test rules in a staging environment first. Use:
php artisan fractor:process --dry-run | grep -E 'RewriteRule|ErrorDocument'
To validate output before applying.
Log Rule Output Temporarily log processed lines to debug:
public function process(array $htaccessLines): array
{
\Log::debug('Processed lines:', $htaccessLines);
return $htaccessLines;
}
Check File Permissions
Ensure Fractor has read/write access to .htaccess files (especially on shared hosting). Use:
chmod -R 755 storage bootstrap/cache
Tagging Issues If rules aren’t loaded, verify the service provider is registered and tags are correct:
php artisan tag:list fractor.htaccess_rule
Custom Processors
Extend HtaccessFileProcessor to add pre/post-processing logic:
class CustomHtaccessProcessor extends HtaccessFileProcessor
{
protected function preProcess(array $htaccessLines): array
{
return array_map('trim', $htaccessLines);
}
}
Dynamic Rule Loading Load rules from a database or config file:
$rules = config('fractor.htaccess_rules');
foreach ($rules as $ruleClass) {
$this->app->tag([$ruleClass], 'fractor.htaccess_rule');
}
Git Integration
Use Fractor in a CI pipeline to validate .htaccess files before commits:
# .github/workflows/htaccess-lint.yml
jobs:
lint-htaccess:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: composer require a9f/fractor-htaccess --dev
- run: php artisan fractor:process --dry-run
How can I help you explore Laravel packages today?