Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Htaccess Parser Laravel Package

tivie/htaccess-parser

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require tivie/htaccess-parser
    

    Add to composer.json under require:

    "tivie/htaccess-parser": "^0.4.0"
    
  2. First Use Case: Parse an existing .htaccess file:

    use Tivie\HtaccessParser\Parser;
    
    $parser = new Parser();
    $htaccess = $parser->parse(new \SplFileObject(public_path('.htaccess')));
    
  3. Key Classes to Know:

    • Parser: Core class for parsing .htaccess files.
    • HtaccessContainer: Stores parsed tokens (directives, blocks, etc.).
    • TokenInterface: Base interface for all token types (directives, blocks, comments).

Implementation Patterns

Common Workflows

1. Dynamic .htaccess Generation

Useful for Laravel deployments or multi-environment configs:

$htaccess = new \Tivie\HtaccessParser\HtaccessContainer();
$htaccess[] = new \Tivie\HtaccessParser\Token\Directive('RewriteEngine', 'On');
$htaccess[] = new \Tivie\HtaccessParser\Token\Directive('RewriteRule', '^$', 'public/index.php');

file_put_contents(public_path('.htaccess'), (string)$htaccess);

2. Conditional Block Injection

Add environment-specific rules (e.g., staging vs. production):

$htaccess = $parser->parse(new \SplFileObject(public_path('.htaccess')));

if (app()->environment('staging')) {
    $block = new \Tivie\HtaccessParser\Token\Block('IfModule', 'mod_rewrite.c');
    $block->addToken(new \Tivie\HtaccessParser\Token\Directive('RewriteRule', '^$', 'staging/index.php'));
    $htaccess->insertAt(0, $block);
}

file_put_contents(public_path('.htaccess'), (string)$htaccess);

3. Validation and Sanitization

Remove or modify unsafe directives (e.g., AllowOverride):

$htaccess = $parser->parse(new \SplFileObject(public_path('.htaccess')));

foreach ($htaccess as $token) {
    if ($token instanceof \Tivie\HtaccessParser\Token\Directive && $token->getName() === 'AllowOverride') {
        $token->setArguments('None'); // Force strict permissions
    }
}

file_put_contents(public_path('.htaccess'), (string)$htaccess);

4. Search and Replace

Update directives across multiple files (e.g., for Laravel migrations):

$htaccess = $parser->parse(new \SplFileObject(public_path('.htaccess')));
$htaccess->search('mod_rewrite')->setName('mod_rewrite'); // Case-insensitive fix

// Replace all occurrences of `Options -MultiViews` with `Options +FollowSymLinks`
foreach ($htaccess as $token) {
    if ($token instanceof \Tivie\HtaccessParser\Token\Directive &&
        $token->getName() === 'Options' &&
        in_array('-MultiViews', $token->getArguments())) {
        $token->setArguments('+FollowSymLinks');
    }
}

5. Integration with Laravel Service Providers

Bootstrapping .htaccess manipulation in a service provider:

public function boot()
{
    $parser = new Parser();
    $htaccess = $parser->parse(new \SplFileObject(public_path('.htaccess')));

    // Add Laravel-specific rules
    $htaccess[] = new \Tivie\HtaccessParser\Token\Directive('DirectoryIndex', 'index.php');
    $htaccess[] = new \Tivie\HtaccessParser\Token\Block('FilesMatch', '\.php$')
        ->addToken(new \Tivie\HtaccessParser\Token\Directive('SetHandler', 'proxy:unix:/run/php/php8.2-fpm.sock'));

    file_put_contents(public_path('.htaccess'), (string)$htaccess);
}

Integration Tips

Laravel-Specific Use Cases

  1. Environment-Aware Parsing: Use Laravel’s config to toggle parsing behavior:

    $parser = new Parser();
    $parser->ignoreComments(config('htaccess.ignore_comments', false));
    $parser->ignoreWhiteLines(config('htaccess.ignore_whitespace', true));
    
  2. Artisan Commands: Create a custom command for .htaccess management:

    use Illuminate\Console\Command;
    use Tivie\HtaccessParser\Parser;
    
    class HtaccessCommand extends Command
    {
        protected $signature = 'htaccess:generate {--env=production}';
        protected $description = 'Generate optimized .htaccess';
    
        public function handle()
        {
            $parser = new Parser();
            $htaccess = $parser->parse(new \SplFileObject(public_path('.htaccess')));
    
            // Apply env-specific rules
            if ($this->option('env') === 'staging') {
                $this->addStagingRules($htaccess);
            }
    
            file_put_contents(public_path('.htaccess'), (string)$htaccess);
            $this->info('Regenerated .htaccess');
        }
    }
    
  3. Package Development: Bundle .htaccess templates and merge them dynamically:

    public function install()
    {
        $template = new \Tivie\HtaccessParser\HtaccessContainer();
        $template[] = new \Tivie\HtaccessParser\Token\Directive('RewriteEngine', 'On');
        $template[] = new \Tivie\HtaccessParser\Token\Directive('RewriteBase', '/');
    
        $userHtaccess = $this->parser->parse(new \SplFileObject(public_path('.htaccess')));
        $merged = array_merge($template, $userHtaccess);
    
        file_put_contents(public_path('.htaccess'), (string)new \Tivie\HtaccessParser\HtaccessContainer($merged));
    }
    

Gotchas and Tips

Pitfalls

  1. Case Sensitivity in Blocks: Block names (e.g., <IfModule>) are case-insensitive in .htaccess, but the parser treats them as case-sensitive by default. Use:

    $block = new \Tivie\HtaccessParser\Token\Block('ifmodule', 'mod_rewrite.c');
    

    or override the getName() method in custom blocks.

  2. Multiline Directives: Directives ending with \ (e.g., RewriteCond %{HTTP_HOST} ^example\.com) may not parse correctly. Use useArrays(true) to debug:

    $parser->useArrays(true);
    $tokens = $parser->parse($file);
    print_r($tokens); // Inspect raw structure
    
  3. File Pointer Issues: The parser rewinds the file pointer by default. Disable with:

    $parser->rewindFile(false);
    

    Useful when parsing large files or streams.

  4. Token Modification Side Effects: Modifying a Directive or Block token’s arguments does not validate the syntax. Always test the output:

    $token = new \Tivie\HtaccessParser\Token\Directive('InvalidDirective', 'foo');
    echo (string)$token; // May output malformed syntax
    
  5. Array vs. Object Tokens: When using useArrays(true), tokens become associative arrays. Access properties like:

    $token['name']; // Instead of $token->getName()
    

    But lose type safety and IDE autocompletion.


Debugging Tips

  1. Inspect Tokens: Dump the token structure for debugging:

    $parser->useArrays(true);
    $tokens = $parser->parse(new \SplFileObject(public_path('.htaccess')));
    dd($tokens); // Debug raw token array
    
  2. Validate Output: After modifications, validate the generated .htaccess:

    $output = (string)$htaccess;
    $this->assertStringContainsString('RewriteEngine On', $output);
    
  3. Handle Exceptions: Wrap parsing in a try-catch:

    try {
        $htaccess = $parser->parse($file);
    } catch (\RuntimeException $e) {
        Log::error("HTAccess parse error: " . $e->getMessage());
        throw new \Exception("Failed to parse .htaccess");
    }
    

Extension Points

  1. Custom Token Types: Extend TokenInterface for domain-specific tokens:

    class LaravelDirective implements \Tivie\HtaccessParser\Token\TokenInterface
    {
        public function __toString()
        {
            return "# Laravel: " . $this->getName() . " " . implode(' ', $this->getArguments());
        }
    }
    
  2. Parser Hooks: Override parser methods to add preprocessing:

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
sentix/ai-chatbot
terminal42/code-quality-tools
codifyo/ts-generator-bundle
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky