.htaccess files, PHP, includes directories, and windows XAMPP configuration nightmare - php

XAMPP makes configuring a local LAMP stack for windows a breeze. So it's quite disappointing that enabling .htaccess files is such a nightmare.
My problem:
I've got a PHP application that requires apache/php to search for an /includes/ directory contained within the application. To do this, .htaccess files must be allowed in Apache and the .htaccess file must specify exactly where the includes directory is.
Problem is, I can't get my Apache config to view these .htaccess files. I had major hassles installing this app at uni and getting the admins there to help with the setup. This shouldn't be so hard but for some reason I just can't get Apache to play nice.
This is my setup:
c:\xampp
c:\xampp\htdocs
c:\xampp\apache\conf\httpd.conf - where I've made the changes listed below
c:\xampp\apache\bin\php.ini - where changes to this file affect the PHP installation
It is interesting to note that c:\xampp\php\php.ini changes mean nothing - this is NOT the ini that affects the PHP installation.
The following lines are additions I've made to the httpd.conf file
#AccessFileName .htaccess
AccessFileName htaccess.txt
#
# The following lines prevent .htaccess and .htpasswd
# files from being viewed by Web clients.
#
#<Files ~ "^\.ht">
<Files ~ "^htaccess\.">
Order allow,deny
Deny from all
</Files>
<Directory "c:/xampp/htdocs">
#
# AllowOverride controls what directives may be placed in
# .htaccess files.
# It can be "All", "None", or any combination of the keywords:
# Options FileInfo AuthConfig Limit
#
AllowOverride All
#
# Controls who can get stuff from this server.
#
Order allow,deny
Allow from all
</Directory>
The following is the entire .htaccess file contained in:
c:\xampp\htdocs\application\htaccess.txt
<Files ~ "\.inc$">
Order deny,allow
Deny from all
</Files>
php_value default_charset "UTF-8"
php_value include_path ".;c:\xampp\htdocs\application\includes"
php_value register_globals 0
php_value magic_quotes_gpc 0
php_value magic_quotes_runtime 0
php_value magic_quotes_sybase 0
php_value session.use_cookies 1
php_value session.use_only_cookies 0
php_value session.use_trans_sid 1
php_value session.gc_maxlifetime 3600
php_value arg_separator.output "&"
php_value url_rewriter.tags "a=href,area=href,frame=src,input=src,fieldset="
The includes directory exists at the location specified.
When I try to access the application I receive the following error:
Warning: require(include.general.inc) [function.require]: failed to open stream: No such file or directory in C:\xampp\htdocs\application\menu\logon.php on line 21
Fatal error: require() [function.require]: Failed opening required include.general.inc (include_path='.;C:\xampp\php\pear\random') in C:\xampp\htdocs\application\menu\logon.php on line 21
The include path c..\random\ is specified in the php.ini file listed above. The XAMPP install fails to allow another include path as specified in the htaccess.txt file.
I'm guessing there's probably an error with the httpd.conf OR the htaccess.txt file.. but it doesn't seem to be reading the .htaccess file. I've tried to be as thorough as possible so forgive the verbosity of the post.
Now I know a workaround could be to simply add the include_path to the PHP file, but I'm not going to have access to the php.ini file on the location I plan to deploy my app. I will, however, be able to request the server admin allows .htaccess files.
renamed htacces.txt to .htaccess and ammended the appropriate directives in the httpd.conf file and all seems to work. The application suggested the naming of htaccess.txt and the ammended directives in the httpd. These are obviously wrong (at least for a XAMPP stack).
By the way, using ini_set() is a much friendlier way if the app needs to be deployed to multiple locations so thanks especially for that pointer.

Why do you need to rename .htaccess to htaccess.txt
Try setting the include_path using set_include_path() and see if that helps (as an intermediate fix)
Verify which php.ini to use through a phpinfo()

You can alter the include_path on each request using ini_set(). This would avoid having to use htaccess at all.

My htaccess works under XAMPP fine - though some modules are disabled by default - are you sure that the modules you want are enabled?

I think the searchprase you are looking for is:
AllowOverride All
My guess is that within xampp you need to enable AllowOverride (through an .htaccess) in httpd.conf. It's a simple security measure that prevents newbies from installing a hackable platform :P

You need to enable AllowOverride All in main http.conf file. Look inside XAMPP_DIR/apache/conf/http.conf)

Simply Do this:
open file ...\xampp\apache\conf\httpd.conf
find line "LoadModule rewrite_module modules/mod_rewrite.so"
if here is a # before this line remove it.(remove comment)
its working

Related

Using heroku-fcgi to handle files without a .php extension (Apache)

Overview
I'm trying to host a few legacy PHP apps on Heroku with Apache. They all relied on the following deprecated syntax to parse any unknown file types (without the .php extension) as PHP.
DefaultType application/x-httpd-php
This has been replaced by AddType in Apache 2.4 (Heroku currently uses v2.4.37). Heroku also uses mod_proxy_fcgi to process PHP files via fcgi://heroku-fcgi.
Issue
I have a file foo.test and I want to have it handled by PHP FPM. Taking cues from the docs and the default Apache config provided by Heroku, here's what I've tried:
# .htaccess
<FilesMatch \.test$>
<If "-f %{REQUEST_FILENAME}">
SetHandler proxy:fcgi://heroku-fcgi
</If>
</FilesMatch>
# apache_app.conf (properly loaded via Procfile)
ProxyPassMatch "^/(.*\.test(/.*)?)$" "fcgi://heroku-fcgi/app/$1"
With both of these I get a plain-text 403 Access denied. response from PHP FPM. I'm sure both configs are properly loading and pointing to the FCGI handler because changing the endpoint results in other errors.
My Apache skills are long since rusty and I can't seem to find any good pointers online. The Apache error log is also clean. Any ideas (without the obvious "change all extensions to PHP, you dumbass") would be appreciated!
Fairly obvious solution. PHP FPM has its own configuration with a security.limit_extensions flag. It defaults to .php.
The solution was to unset that value: security.limit_extensions =. This naturally can pose some security threats, but these apps are only going up for static demo.
I was using heroku/heroku-buildpack-php but forked that to update this file. The htaccess FilesMatch should work now but I just ended up placing it into the Apache config file to avoid repetition across the sites I'll be serving.
security.limit_extensions can be customized with a configuration file passed as a Procfile argument.
https://devcenter.heroku.com/articles/custom-php-settings#php-fpm-settings
PHP-FPM settings:
In addition to php_value and php_flag for php.ini specific settings, any pool specific PHP-FPM configuration directives are valid in that configuration file, so you can use it to fine tune PHP-FPM’s behavior.
So you can set up it like the following
Procfile
web: vendor/bin/heroku-php-apache2 -C apache.conf -F fpm_custom.conf web/
apache.conf
<FilesMatch \.test$>
<If "-f %{REQUEST_FILENAME}"> # make sure the file exists so that if not, Apache will show its 404 page and not FPM
SetHandler proxy:fcgi://heroku-fcgi
</If>
</FilesMatch>
fpm_custom.conf
security.limit_extensions = .php .test

how do I enable execution of php scripts in the per-user public_html directories

I have a php script to upload files in a directory.
This works fine in apache's DocumentRoot.
When I copy the code in my /home/$USER/public_html , instead of the right output I just when a printout of the php file. I presume it does not get executed.
I was looking into the userDir module and found this
Options MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec
includesNoExec looked promising but it is related to cgi only.
So how can I enable php scripts to be executed for every user?
Try setting this configuration:
<IfModule mod_userdir.c>
<Directory /home/*/public_html>
php_admin_value engine On
</Directory>
</IfModule>
Don't forget to restart Apache.
service apache2 restart
It turns out the important bit of code that Claudix provided is already present in the configuration files under /etc/apache2/mods-available/php5.conf
the clause there contains php_admin_value engine Off , so by setting the Claudix solution anywhere will conflict with this setting. What is more, the comment above suggests NOT to set php_admin_value engine On as it renders .htaccess files unable to disable php.
As such the correct way to run php in user www directories is by commenting out the relevant text in /etc/apache2/mods-available/php5.conf
I assume you are using apache2 on debian like I do and I think the solution
for you is to add Alias dir and set that alias dir config like below
1 edit the apache2 configuration from terminal run this command
sudo gedit /etc/apache2/sites-enabled/000-default
2 edit the path you will to execute PHP files and save
Alias /testdir /home/user/testdir
<Directory /home/user/testdir>
Options FollowSymLinks
DirectoryIndex index.php
AllowOverride All
</Directory>
3 restart apache2
sudo service apache2 restart
check If you can access the folder from browser if not probably you will have to chmod/chown the folder
yourhost/testdir
According to Apache 2.2 documentation this can be done by uncommenting this configuration line:
#Include conf/extra/httpd-userdir.conf
and modifying httpd-userdir.conf to suit your server. Based on your qustion text, this should resolve your issue.

How do I create custom php.ini files for each virtual host?

I've installed EasyPHP WAMP for local development only (I'm not hosting any websites).
Is there a way to set custom php settings for separate virtual hosts?
Currently and out-of-the-box, the php.ini file is loaded from: C:\Program Files (x86)\EasyPHP-DevServer-14.1VC11\binaries\php\php_runningversion\php.ini It would be nice if, say, I could drop in a custom php.ini file into the virtual host directory to override settings in the original php.ini This way, I could better emulate a production server's environment on a per-site basis.
I've seen this work with online hosting accounts. But I can't figure out how to make this work on my machine.
Using custom php.ini files is pretty straighforward for CGI/FastCGI based PHP installations but it isn't feasible when running PHP as Apache module (mod_php) because the whole server runs a single instance of the PHP interpreter.
My advice:
Set from PHP itself as many settings as you can:
ini_set('memory_limit', '16M');
date_default_timezone_set('Europe/Madrid')
...
In other words, directives that can be changed at runtime.
Set the rest of stuff from per-directory Apache setting files (aka .htaccess):
php_flag short_open_tag off
php_value post_max_size 50M
php_value upload_max_filesize 50M
i.e., settings that need to be defined before the script starts running
Please have a look at the Runtime Configuration for further details.
Sometimes, you'll actually need different settings in development and production. There're endless ways to solve that with PHP code (from creating a boolean constant from the $_SERVER['HTTP_HOST'] variable to just having a config.php file with different values) but it's trickier with .htaccess. I normally use the <IfDefine> directive:
<IfDefine DEV-BOX>
#
# Local server directives
#
SetEnv DEVELOPMENT "1"
php_flag display_startup_errors on
php_flag display_errors on
php_flag log_errors off
#php_value error_log ...
</IfDefine>
<IfDefine !DEV-BOX>
#
# Internet server directives
#
php_flag display_startup_errors off
php_flag display_errors off
php_flag log_errors on
php_value error_log "/home/foo/log/php-error.log"
</IfDefine>
... where DEV-BOX is a string I pass to the local Apache command-line:
C:\Apache24\bin\httpd.exe -D DEV-BOX
If you run Apache as service, the -D DEV-BOX bit can be added in the Windows registry, e.g.:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\Apache2.4\Parameters\ConfigArgs
Related: Find out how PHP is running on server (CGI OR fastCGI OR mod_php)
Developing Multiple Domains on One Machine?
Embedding php.ini settings in the httpd-vhost.conf, typically found in your server root under conf/extra/, is a great way to solve this common problem. If you never knew you could do this, see the PHP.net Manual under How To Change Configuration Settings. This will solve the pesky include_path problem, without adding configuration code to your bootstrapping code or anything else.
Of course, to use this effectively as localhost, you would need to make copies of a <VirualHost> block and configure each accordingly. Then, comment out all virtual host blocks except the one that you want to use!
Alternatively, one could start Apache with the -f option to point the server daemon to a different httpd.conf upon starting. Each httpd.conf would require an "if module block," such as and <IfModule phpx_module> block. Be sure to remember to account for Apache logging!
httpd -f /usr/local/apache2/conf/domains/fooDomain.conf
httpd -f /usr/local/apache2/conf/domains/barDomain.conf
Virtual Host Block With php.ini statements.
<VirtualHost 127.0.0.1:80>
UseCanonicalName On
ServerName localhost:80
ServerAdmin you#localhost
CustomLog "/var/www/someDomain.com/data/logs/httpd_access_log" common
ErrorLog "/var/www/someDomain.com/data/logs/httpd_error_log"
LogLevel warn
DocumentRoot "/var/www/someDomain.com/public"
<Directory "/var/www/someDomain.com/public">
# disable directory listing
Options -Indexes +FollowSymLinks
AllowOverride FileInfo
Require all granted
</Directory>
<IfModule alias_module>
# Alias /webpath /full/filesystem/path
ScriptAlias /cgi-bin/ "/var/www/someDomain.com/scripts/cgi-bin/"
</IfModule>
<IfModule php7_module>
# Use php7_module in opening statement above if on PHP 7+
# Domain specific PHP configuration options.
# The Apache process user must own any of the following directories.
php_admin_value include_path "/var/www/someDomain.com/application/controllers:/var/www/someDomain.com/application/models:/var/www/someDomain.com/application/views"
# Errors and Logging
php_admin_flag display_startup_errors off
php_admin_flag display_errors off
php_admin_flag html_errors off
php_admin_flag log_errors on
php_admin_value error_log "/var/www/someDomain.com/data/logs/php_error_log"
# File Related
php_admin_flag file_uploads on
php_admin_value upload_tmp_dir "/var/www/someDomain.com/data/uploads"
php_admin_value upload_max_filesize 10M
php_admin_value max_file_uploads 5
# Sessions
php_value session.save_handler "files"
php_value session.save_path "/var/www/someDomain.com/data/sessions"
# Caching
php_value soap.wsdl_cache_dir "/var/www/someDomain.com/data/cache/sopa.wsdl"
</IfModule>
</VirtualHost>
If you could use the %{SERVER_NAME} variable in conjunction with the <IfModule phpx_module> blocks to form a compound conditional, you could have just one httpd.conf`, or include a extra/php.conf with all the domain specific PHP.ini settings (in blocks, also). However, as long as "localhost" is the domain target, it will not do what you want. Thus, my answer in the virtual host block above.
Simple way to use custom php.ini file for vhost using Fast CGI is to copy the php.ini into a folder in the host like "customini".
After that to your vhost directive and add this simple line :
FcgidInitialEnv PHPRC "/path_to_your_custom_ini_dir_for_this_vhost/"
BE SURE TO HAVE / to your path no \, (it won't work with \)
Restart Apache.
That's all!
Full sample (on Windows Server here) :
<VirtualHost *:80>
DocumentRoot "C:/APACHE/htdocs/vhost/myvhost"
ServerName www.vhost.com
FcgidInitialEnv PHPRC "C:/APACHE/customini/myvhost/"
</VirtualHost>
Several commentors have mention Vagrant which is an excellent solution.
If you're not interested in using Vagrant, you can investigate using FastCGI as your interface to Apache and using the SetEnv PHPRC... suggestion proposed on this blog:
Apache & PHP: Multiple PHP.ini Configuration Files (Sunday, February 8, 2009)
Source: http://hyponiq.blogspot.com/2009/02/apache-php-multiple-phpini.html
The second work-around is to use the PHPRC environment variable
configurable in Apache using the SetEnv directive. This directive
allows you to set an environment variable that is then passed to any
CGI script and/or Server Side Include (SSI) set in any static (x)HTML
page (or other document type). In this instance, you'd be telling each
PHP-CGI instance where to find its configuration settings. The example
would be (coinciding with the previous one):
# vhosts.conf
NameVirtualHost *:81
<VirtualHost *:81>
ServerAdmin admin#example.com
ServerName vhost.example.com
DocumentRoot "C:/path/to/doc/root"
ErrorLog "logs/vhost.example.com-errors.log"
# Set the PHPRC environment variable
SetEnv PHPRC "C:/path/to/doc/root/php.ini"
<Directory "C:/path/to/doc/root">
# ... yadda, yadda, yadda ...
# you get the point!
</Directory>
</VirtualHost>
However, the PHP documentation changing the runtime
configuration
suggests that you can use certain values like php_value to try
loaalong with, possibly the SetEnv directive.
He suggests another option not using FastCGI, instead leveraging the php_value, php_flag etc. configuration options.
Other's seem to have had some success with executing scripts through FastCGI though, see: Separate php.ini for different virtual hosts
Other suggestions involve the PHPINI directive, which may be pertinent for your needs, see: How do I limit PHP apps to their own directories and their own php.ini?

.htaccess php_value include_path not working

I have a small project in local. I'm working under Windows and with XAMPP. My file directory structure is:
Root directory: C:\xampp\htdocs\routes
Under this folder, I have my bootstrap.php with the configuration I want to initialize my project.
Public folder: C:\xampp\htdocs\routes\htdocs
Under this folder I have my index.php and my .htaccess.
Inside this .htaccess I have the following configuration:
php_value include_path .:/routes
php_value auto_prepend_file bootstrap.php
If I do a get_include_path() inside the index.php, it shows ".:/routes".
But the message I get on my web browsers (after typing http://localhost/routes/htdocs) all the time is:
Fatal error: Unknown: Failed opening required 'bootstrap.php' (include_path='.:/routes') in Unknown on line 0
I have tried a lot of combinations of include_path inside the .htaccess:
php_value include_path ".:/routes"
php_value include_path .:../routes
php_value include_path ".:./routes"
php_value include_path ".:routes"
...
The configuration of my httpd.conf is:
DocumentRoot "C:/xampp/htdocs"
<Directory />
AllowOverride none
Require all denied
</Directory>
<Directory /routes>
AllowOverride all
</Directory>
If I hard code the info in bootstrap inside the index.php, it works (at least this tells me the requirements inside bootstrap are well configured).
I don't know what to do for my project to recognize the bootstrap.php.
What am I missing? What am I doing wrong?
Thank you in advance for your help
First, the <Directory> block has no effect for include. Since this is not an Apache query, but rather a preprocessing order.
Second, use absolute paths in your include_path, to make it independent from where your files are sitting.
Third, make sure the path to bootstrap.php is openable by the user your webserver runs as, and that the file itself is readable.
if you are using Windows it should be ;
php_value include_path ".;./routes"

php include in .htaccess not getting set

I am trying to set the include path for php in my htaccess file. It works on my local computer but on my dev server it doesn't work. Both ubuntun running apache2.2 Here is my .htaccess file:
AddType application/x-httpd-php .html .htm .php
# ---------------------------------------------------------------------------
# PHP.INI VALUES
# Upload Variables, Include Path, Etc
# ---------------------------------------------------------------------------
php_value include_path "/var/www/includes:.:/usr/local/lib/php:/var/www/"
php_value upload_max_filesize 5242880
php_value post_max_size 5242880
php_value memory_limit 32M
# ---------------------------------------------------------------------------
# Prepend File
# ---------------------------------------------------------------------------
php_value auto_prepend_file "/var/www/includes/prepend.php"
<Limit GET POST>
order deny,allow
deny from all
allow from all
</Limit>
<Limit PUT DELETE>
order deny,allow
deny from all
</Limit>
I am lost as to why this isn't working. Any ideas?
The apache error is saying:
PHP Fatal error: require_once(): Failed opening required 'db.inc.php' (include_oath='.:/usr/share/php:/usr/share/pear') in /var/www/concert2.php on line 3
Check:
Your directory structure is the exact same
Apache has permissions to read this file
The path in your code. Make sure there's no typos, etc.
This related article might help:
PHP Fatal Error Failed opening required File
In my experience, these problems are almost always either path related (you're not actually pointing where you think you're pointing) or permissions related.

Categories