What I would like to do is to create a repeating pattern inside a rewriterule. For example:

RewriteRule ^([\w]+)/([\w]+)/(([\w]+)/([\w]+))*/?$ index.php?p=$1&s=$2(&$4=$5)*


Breaking it down:

On every page my ?p=BLA refers to a certain page, and every &s=BLA refers to a certain subpage. The rewriterule for this would obviously be:

RewriteRule ^([\w]+)/([\w]+)/?$ index.php?p=$1&s=$2

But now I want to add custom $_GET data to my url. For example I want to add &search=SEARCH, and I want to add &page=15, and anotherquery=BLA. The rewriterule I just wrote does not support this.

Is there any way to support an unspecified number of arguments in a rewriterule? For example by creating a repeating pattern? Because I don't know how many new arguments I want to add to the URL in advance.

Dani AI

Generated

raised the core question: how to accept an unspecified number of arguments in a RewriteRule. ’s big optional-group regex is technically possible but brittle (it still has a fixed max number of captures). ’s front-controller idea is the pragmatic, maintainable choice: keep the rewrite simple and let application code parse an arbitrary-depth path.

A concise, robust .htaccess approach is to route non-file/non-directory requests to a single entry script and preserve any existing query string:

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L,QSA]

This avoids complex regexes in Apache and relies on application logic to interpret the path. See the Apache mod_rewrite documentation for details. (https://httpd.apache.org/docs/current/mod/mod_rewrite.html)

Inside the front controller, the path can be split into segments and converted to named parameters or key/value pairs. Example PHP parsing pattern (safe decoding and basic validation expected):

$path = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
$parts = array_values(array_filter(explode('/', trim($path, '/'))));
$p = $parts[0] ?? null;
$s = $parts[1] ?? null;

$params = [];
for ($i = 2; $i < count($parts); $i += 2) {
  $k = $parts[$i];
  $v = $parts[$i+1] ?? null;
  $params[$k] = rawurldecode($v);
}

The remaining elements in $params can be validated (e.g., intval for page numbers, whitelist keys) and optionally merged into $_GET. PHP’s parse_url and the $_SERVER docs are useful references. (https://www.php.net/manual/en/function.parse-url.php) (https://www.php.net/manual/en/reserved.variables.server.php)

Troubleshooting notes: ensure mod_rewrite and AllowOverride are enabled, test with various trailing-slash forms, and prefer application-level validation over trusting path content. Large, nested regex rules are hard to maintain; the front-controller pattern is simpler and scales to unlimited arguments.

Recommended Answers

All 5 Replies

Well it is possible to do if statements in regex like the following:

RewriteRule ^/?([\w]+)/(([\w]+)/(([\w]+)/(([\w]+)/(([\w]+)/(([\w]+)/(([\w]+)/|)|)|)|)|)|)$ index.php?a=$1&b=$3&c=$5&d=$7&e=$9&f=$11&g=$13

And in that regex up the 7 forward slashes may be used with [\w]+ between them. It will dynamically match from 1 forward slash to 7 foward slashes. But keep in mind for it to work you will need it to match [\w]+.

I have ran into this problem and I solve it by using php to handle this. Pretty much you send the entire url to a php page in a url variable.

Ex.

RewriteRule ^(.*)$ your_page.php?_url_=$1

Then with php you get the data and parse it yourself.

if ( isset( $_GET['_url_'] ) ) {
  //parse url
}

Worked great and still does in my custom mvc framework.

Maybe not the solution you are wanting, but will give you the flexibility you require.

Well it is possible to do if statements in regex like the following:

RewriteRule ^/?([\w]+)/(([\w]+)/(([\w]+)/(([\w]+)/(([\w]+)/(([\w]+)/(([\w]+)/|)|)|)|)|)|)$ index.php?a=$1&b=$3&c=$5&d=$7&e=$9&f=$11&g=$13

And in that regex up the 7 forward slashes may be used with [\w]+ between them. It will dynamically match from 1 forward slash to 7 foward slashes. But keep in mind for it to work you will need it to match [\w]+.

Thanks for the answer, that's definitely good to know. However, I have never seen a | being used inside a regex (in that place, I have of course seen it being used inside a pattern with the meaning this "or" that). What's the use of it behind a section?

I have ran into this problem and I solve it by using php to handle this. Pretty much you send the entire url to a php page in a url variable.

Ex.

RewriteRule ^(.*)$ your_page.php?_url_=$1

Then with php you get the data and parse it yourself.

if ( isset( $_GET['_url_'] ) ) {
  //parse url
}

Worked great and still does in my custom mvc framework.

Maybe not the solution you are wanting, but will give you the flexibility you require.

Very inventive. Might give it a try :). Thanks!

Thanks for the answer, that's definitely good to know. However, I have never seen a | being used inside a regex (in that place, I have of course seen it being used inside a pattern with the meaning this "or" that). What's the use of it behind a section?

Yes in regex it also acts as an "or" statement so you can have multiple regex patterns between the "or" statements.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.