"No input file specified" after mod_rewrite rule

I’ve done some extensive reading and searching on mod_rewrite… but it seems like all the examples I see show me exactly what I’m already doing but that isn’t working for me. It’s a fairly simple “pretty url” type of thing trying to hide the index.php part of the URL in my CMS. Here’s my .htaccess file:


<IfModule mod_rewrite.c>
Options +FollowSymLinks
RewriteEngine On
RewriteBase /

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d

RewriteRule (.*) index.php/$1

</IfModule>

The RewriteRule should make it so that someone can enter mysite.com/pretty and get to mysite.com/index.php/pretty. But when I try, I just get a message saying “No input file specified”… I guess from my CMS.

The thing is, if I change the rule to an external redirect, like this…

RewriteRule (.*) http://www.mysite.com/index.php/$1

…it works faithfully. But that’s not very helpful because then the browser shows the whole URL with the index.php.

It seems like I’m doing things exactly the way that all the manuals and guides suggest, but it’s obviously not turning out. It’s a pretty simple rule, so I’m puzzled.

Any help?

Ben,

THANK YOU for your generous comments and suggestion! :blush: Because one of the apache.org people (Dan Bowen) already wrote such a book (focused on using mod_rewrite in the httpd.conf rather than .htaccess - maybe I could write to that niche), I’d not given it much credence. It might work - I’ll have to approach SitePoint about that after my current project (passing the Certified Ethical Hacker exam with flying colors).

Yes, you’ve hit it on the head! PERFECT!

Regards,

DK

B+,

Hmmm, the first “problem” I see is that you do not understand regex. Do you not think that the :kaioken: EVERYTHING :kaioken: atom will match “index.php/pretty” just as easily at it matches “pretty”?

Second problem is that you are abusing your server. WHY would you ask it to test whether mod_rewrite is enabled for EVERY request made to your website? I normally rant about a member NOT being a webmaster for such abuse but …

The third problem is a little more innocuous: index.php/pretty is NOT a file that Apache can serve. Big surprise, I know! Okay, IF (and ONLY IF) you have enabled MultiViews can a “directory” in a path hijack the request (as you seem to prefer). Because MultiViews causes many problems, I prefer to turn it off and keep it off - which would cause your redirection to fail (in the manner it’s doing now).

The fourth problem is that your mod_rewrite block statement is not terminated, i.e., no Last flag. You’d not get away with that in you PHP code so why would you do that with mod_rewrite? While you’re at it, add an R=301 flag just so you can see that your mod_rewrite is working and has redirected to index.php/pretty (and can’t find “pretty” in the index.php directory). Using the R=301 flag is a very useful troubleshooting tool as you can remove it to keep the redirection hidden once you’ve shaken out the bugs.

Edit:

Oh, yeah, the fifth problem is in using the RewriteBase command which is intended to UNDO a mod_alias redirection. Here, it does nothing useful (therefore, it should be removed) and it could cause problems by changing the base directory (DocumentRoot) when it’s not expected. The message here is “don’t use code you don’t understand.”

Regards,

DK

Hi DK,

I very much appreciate your help, but I very much DON’T appreciate your attitude. I’m obviously a novice with Apache configuration – it’s not my area of expertise – but I’m trying to get a job done based on what my CMS is recommending and some online tutorials and documentation I’ve read. What I posted there was pretty much exactly what my CMS gave me, except that I added the Options +FollowSymLinks line and left out the [L]. I also removed a ^ and a $ from before and after the (.*) part because they seemed unnecessary. I came to Sitepoint Forums for some guidance after reading tutorials and seeing the same or similar code recommended, yet it still wasn’t working for me. I’ve looked at a little of the official Apache documentation, but I find it hard to understand.

If I understand you correctly, the problem with the way I’ve used the everything atom is that the module would attempt to rewrite an address like mysite.com/index.php/pretty to mysite.com/index.php/index.php/pretty, is that right? I actually was wondering that myself, but since I could visit mysite.com/index.php/pretty with no incident, I didn’t challenge it.

I get your point about not needing the IfModule and so I removed it. It was part of what my CMS gave me and I’ve seen it elsewhere, for instance in a Sitepoint article and in the affiliate software I have. I think I even recall reading a tutorial that recommended it on the basis of “it takes Apache about a nanosecond or two to test for the module, so why not?”. Obviously, it’s a widespread “abuse”, if you could call it that.

I gather that you’re suggesting the problem might be that I have MultiViews off and that’s what’s causing the rewrite to fail, but that it might be better to have it off anyway. I don’t know much about MultiViews and I’ll have to check whether it’s on or off. If I keep it off, is there another way to accomplish the kind of rewriting I’m attempting?

As for the fourth problem, I was doing some experimentation and removed the [L] flag and then forgot to put it back when I posted. I’ve put it back and will try adding the R=301 for testing. Thanks for the tip.

Now, the RewriteBase / part is another one of those things I see all over the place. Maybe it’s a game of copycat. However, when I removed it from my .htaccess file, I started getting addesses like mysite.com/users/home/iridium/web/public/index.php/users/home/iridium/web/public/index.php/…………… So I guess there was something useful it was doing.

I saw all the mod_rewrite questions in the Apache forum and I can imagine that as a top contributor you’re tired of them. I saw the sticky posts and visited and read some of the resources there. I posted because I didn’t find the answer and I wanted some guidance.

What I didn’t need was a bunch of incriminating questions thrown back at me. I didn’t need to have flaming angry faces punctuating the everything atom. I didn’t need to feel like I was reading a personal litany of all the ways you find me to be incompetent with mod_rewrite, like each error was an egregious offense.

I’m no regex expert, but to start off saying that I don’t understand regex is inflammatory. I use regular expressions in my PHP and Javascript code and I get by quite well. I’m obviously a beginner with mod_rewrite, but it’s like you’re taking a child who’s just learning the alphabet and thundering at him “You wouldn’t walk to school backwards, SO WHY WOULD YOU WRITE YOUR ‘S’ BACKWARDS?!?!?!” I can certainly appreciate the sentiment of “don’t use code you don’t understand”, but the fact is that as web developers most of us end up doing a little of everything and venturing out on terrain we’re not too sure about where a little gentle guidance would be appreciated. I don’t suppose you’ve ever been in that kind of a situation, have you?

Anyway, the point is that I thought this was a learning community. I do not wish to abuse the precious server. Please do not abuse your fellow forum members. Maybe you get off on being the grand judge and jury, but if that’s the way you’re going to serve up your expertise, then I’ll have to say no thank you. If you want to help me learn, I welcome your feedback, but please treat me more respectfully.

You’ve given me some helpful points, thank you. I’m going to read your mod_rewrite article and look up MultiViews and try to figure this out.

Thanks,

Ben

Hi Ben,

Sorry, I was not picking on you. I do get frustrated with members asking the same questions day after day, week after week, month after month and year after year. I got so tired of answering the same questions all the time that I wrote the mod_rewrite tutorial linked in my signature (and copied to the stickies you bypassed on entry) and it does no good. No, it’s not you, it’s everyone. Okay, I give up and ask, too, when I can’t find something I am looking for right away - this IS the age of instant gratification!

Okay, now on to comment on your post.

Just because something is used by someone else (or in your CMS) doesn’t mean it’s a good thing. The CMS people (okay, WordPress in particular) have written their mod_rewrite to prevent 500 errors (when mod_rewrite isn’t enabled) and it assumes that it must capture EVERYTHING and redirect to index.php. Well, it works for their system but … the idea that I try to impress on members is that you DON’T want to use code just because it’s available. PLEASE understand the code you’re using!

Options +FollowSymLinks should already be in the httpd.conf. If it’s not, it’s fine to add it.

The Last flag is a (minor) pet peeve as noobies tend to ignore it and don’t understand why the second RewriteRule (and subsequent RewriteRules) in a series is never matched and redirected. It’s seemingly minor but IS a big deal.

The start and end anchors can probably be omitted in certain circumstances (because (.*) is greedy).

To understand the (.*), you must understand

  1. That it will match NOTHING or EVERYTHING

  2. mod_rewrite loops back through making successive passes through the set of mod_rewrite statements until no match/redirection is made. That causes it to re-process a RewriteRule with (.*) … so there MUST be a way to escape the match/redirection! (Apache 1.x was very unforgiving on this point as it would continue to loop until it had to be shut down and restarted (that’s why most hosts refused to allow you to write to .htaccess or failed to enable mod_rewrite). Apache 2.x will only allow 10 loops before stopping mod_rewrite.) You can avoid these problems by:

a. Replacing the (.*) with regex code which will match what you want to redirect (see below)

OR

b. Using a RewriteCond to prevent a match of the redirection’s {REQUEST_URI}.

<IfModule> is the CMS protecting noobie webmasters from 500 errors. It’s a silly noobie mistake to leave it in but understandable if the noob doesn’t know what it’s there for. Chalk that up to a learning experience. :tup:

MultiViews is another noobie buggaboo as it will match just the filename (without an extension) in the path and redirect to that file … before getting to mod_rewrite! IMHO, it’s a major PITA and should be avoided. However, for completeness, I mentioned that because of your redirection (index.php/{whatever}). It’s a personal thing that, because I can hide the redirection with mod_rewrite, I prefer to use query strings which are easier for my PHP scripts to parse (they don’t have to parse the {REQUEST_URI} string, the key/value pairs are in the $_GET [and $_REQUEST] array).

RewriteBase is designed to “undo” the effect of a mod_alias redirect. If you have none of those (that you need to “undo”), why use the thing? Wait until you have a RewriteBase /path statement to wrap your head around while you’re struggling with why a RewriteRule won’t work.

The users/home/whatever URI is the sign of a corrupt Apache - it needs to be restarted as should NEVER display the physical path to your files. It should NEVER display anything in the path outside your webspace!

Actually, I jumped out of the PHP forum (which is why I’d joined years ago) for some help with mod_rewrite. I quickly learned from the master (pippo) and actually asked why one of his recommendations was wrong (I do that, too, on occasion). When pippo went on holiday, I stayed around to answer mod_rewrite questions and … well, I’m still here. Yes, I get tired (ergo the perceived “attitude”) of answering the same questions (as above) but try to convert that into a learning experience (I do get annoyed at the “script kiddies” that want me to code something for them) for all members.

The regex used by mod_rewrite is a subset of Apache’s regex engine - primarily because mod_rewrite is a very simple language. If you’ve every parsed an online page to pick out pieces of the page’s text (to pop into a scroller, for instance), then you know that you can’t merely find the start <p> and (.) then specify an end point as </p> as the (.) will grab everything on the page from the first <p> to the last </p>. The “trick” is to use regex to specify exactly what you will accept rather than use the “lazy regex” of the (.), e.g., ‘~<p id=“some_id”>([a-zA-Z .]+)</p>~’. Even (.?) is better than (.*) … but you already knew that.

And the answer is yes. However, I take the time to understand the code that others are using (CMS, the other posts here, etc.) as you know. Asking questions about the meaning of what’s not understood is my way of learning. My way of teaching is to make members think so they’ll remember the process the next time. No offense was intended and I am sorry that offense was taken.

If you have any questions about the tutorial - or anything else - please fire away. I’m here as a volunteer to help members learn so they don’t have to ask/pay for someone else to do it for them.

Regards,

DK

And such a generous volunteer you are, thank you!! You really should write a book for Sitepoint on mod_rewrite – something that teaches people how to “rewrite right”. I think it’s difficult for people to learn in the “drive-by” context of a forum, but if you laid it all out in a book, they could finally get enough of the picture to line things up correctly and succeed. Truth be told, you’ve probably already written the book in your articles and forum posts, you would just have to stitch them together.

I’ve purchased just about every Sitepoint book that has to do with code and if Sitepoint came out with a mod_rewrite book, I’d buy it in a heartbeat. It seems like mod_rewrite more than anything is where PHP scripters converge with Apache configuration and get into trouble because they don’t really understand the whole picture. Someone needs to write a scripter’s guide to URI rewriting. The Apache documentation is too much geared toward people who actually understand how the internet and servers work (LOL).

Anyway, thank you for your copious explanation – quite refreshing! I suppose a good place for me to start would be with something like:

RewriteCond &#37;{REQUEST_URI} !^index\\.php

What do you think – would that take care of preventing a match of the redirection’s request URI?

Thanks,

Ben

P.S. I did read your article at http://articles.sitepoint.com/article/apache-mod_rewrite-examples and learned about how Apache loops the rewrite maneuvers, which I didn’t realize before. I shall read the one on your website and keep learning.