Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Where is my PHP (FastCGI) getting its settings?

Status
Not open for further replies.

OsakaWebbie

Programmer
Feb 11, 2003
628
JP
Is there a way to get PHP to tell me where it is checking php.ini files for its settings? It feels like my VPS is haunted by ghost settings I can't find. php.ini files I would expect to have an effect don't, and instead PHP gets its ideas from elsewhere (who knows where). The settings I'm currently fighting are magic_quotes_gpc and display_errors, but I'm sure there will be others in the future that I want to control.

My setup is kinda complex, so bear with me. I'm not an expert in server admin, so if my setup is wacky (and/or if you see security holes), please tell me. The objective is a regular website in one spot (with one domain), a subdirectory under that with some code that is still being worked on, and a single-codebase/multi-client application in a different spot (using subdomains of a second domain).

The regular website is in /var/ and as I said, it also has a subdirectory with code under development. Then I have an application that uses a single codebase (in /var/ but each client has a separate database and separate directory for auxiliary files (/var/ Finally, I just installed a development version of the codebase (/var/
In my Apache configuration, I have this stuff (parts of three files, but I think it executes in this order):
Code:
<Directory />
    Options FollowSymLinks
    AllowOverride None
</Directory>

<Directory "/var/[URL unfurl="true"]www/html">[/URL]
    Options -Indexes FollowSymLinks +ExecCGI
    AllowOverride All
    Order allow,deny
    Allow from all
    AddHandler php5-fastcgi .php
    Action php5-fastcgi /cgi-bin/php.fcgi
</Directory>

ScriptAlias /cgi-bin/ "/var/[URL unfurl="true"]www/cgi-bin/"[/URL]
<Directory "/var/[URL unfurl="true"]www/cgi-bin">[/URL]
    AllowOverride None
    Options None
    Order allow,deny
    Allow from all
</Directory>

<VirtualHost *:80>
    ServerName l4jp.com
    DocumentRoot /var/[URL unfurl="true"]www/html[/URL]
    SuexecUserGroup l4jp l4jp
    ScriptAlias /cgi-bin/ "/var/[URL unfurl="true"]www/cgi-bin/"[/URL]
</VirtualHost>

<Directory "/var/[URL unfurl="true"]www/kizunadb/dev">[/URL]
    Options -Indexes FollowSymLinks +ExecCGI
    AllowOverride None
    AddHandler php5-fastcgi .php
    Action php5-fastcgi /cgi-bin/php.fcgi
    Order allow,deny
    Allow from All
</Directory>

<VirtualHost *:80>
    ServerName dev.kizunadb.com
    DocumentRoot /var/[URL unfurl="true"]www/kizunadb/dev[/URL]
    SuexecUserGroup dev kizunadb
    ScriptAlias /cgi-bin/ "/var/[URL unfurl="true"]www/dev/.cgi-bin/"[/URL]
</VirtualHost>

<Directory "/var/[URL unfurl="true"]www/kizunadb/codebase">[/URL]
    Options -Indexes FollowSymLinks +ExecCGI
    AllowOverride None
    AddHandler php5-fastcgi .php
    Action php5-fastcgi /cgi-bin/php.fcgi
    Order allow,deny
    Allow from All
</Directory>

<VirtualHost *:80>
    ServerName clientname.kizunadb.com
    DocumentRoot /var/[URL unfurl="true"]www/kizunadb/codebase[/URL]
    SuexecUserGroup clientname kizunadb
    ScriptAlias /cgi-bin/ "/var/[URL unfurl="true"]www/clientname/.cgi-bin/"[/URL]
</VirtualHost>
# This last vhost section is repeated for each client...

In each client directory (including /var/ there is a .cgi-bin directory with a php.fcgi script and php.ini file (the php.fcgi files are all identical - that's redundant, but I don't know how else to set it up, because the php.ini files need to be distinct). The plan was that the only thing normally in the clients' php.ini files would be open_basedir (to keep them from accessing each other's files). But I can't figure out where the default settings (anything not specified in /var/ are, so I'm having to repeat stuff in each of those files that should just be in the default spot.

The first problem I noticed was with magic_quotes_gpc. OFF should be the default (I have PHP 5.3.3), and there is no php.ini on my whole machine that sets it to ON. But without intervention the setting ends up ON in the KizunaDB area! I tried adding "magic_quotes_gpc = Off" in /etc/php.ini and /var/ but neither have any effect - those files appear to be ignored in my current structure. The only solution I could find was to put that command in all the instances of /var/ which seems excessive, but for now that's what I have to do.

Next I added the subdirectory under the main website. I discovered that display_errors was Off (set that way in /var/ so I was working blind. Reading up on it, I learned that it is good to keep it off for production sites, so I tried to turn it on just for the subdirectory. But a php.ini file placed in the subdirectory is ignored, so I had to change the setting in /var/ which affects the main Joomla website as well (not ideal). I can't figure out any way to keep the settings separate for the main directory and the subdirectory.

Then yesterday I set up the kizunadb/dev development area, and discovered that on that side of the house, display_errors had been ON all along, and that that is the system default when there is no php.ini that applies. So once again, I had to add a specification to each and every client's php.ini to turn it off. I would like to have a default for Kizuna and then just make an exception for dev, or even better, have a default for everything and then make exceptions for dev.kizunadb.com and l4jp.com/subdir. Can someone teach me a little bit about how this works so that I can manage it better?
 
Is there a way to get PHP to tell me where it is checking php.ini files for its settings?

yup. put this code in a file in the same directory and run it.

Code:
<?php phpinfo(); ?>

part of the information that is returned will be the location of the relevant php.ini.

php settings can also be stored in htaccess and httpd files (and those other files that can be included in the above). I use webmin to administer domains on my servers - makes it easy to manage the php settings etc (using flags and admin flags in htaccess), and it doesn't take over the file system like cpanel does (which I hate).
 
Thanks! I have used phpinfo() for years, but I have never gotten familiar with everything in it (way too much stuff - my eyes glaze over), and until you pointed it out, I didn't realize the ini paths were there. Duh!

For the subdirectory of my regular website location, it says this:
[ul]
[li]Configuration File (php.ini) Path: /etc[/li]
[li]Loaded Configuration File: /var/www/cgi-bin/php.ini[/li]
[li]Scan this dir for additional .ini files: /etc/php.d[/li]
[/ul]
That's the same as for its parent directory, so how can I have different settings for the subdirectory?

And here is how it looks for my client subdomains of kizunadb.com:
[ul]
[li]Configuration File (php.ini) Path: /etc[/li]
[li]Loaded Configuration File: /var/www/clientname/.cgi-bin/php.ini[/li]
[li]Scan this dir for additional .ini files: /etc/php.d[/li]
[/ul]
magic_quotes_gpc is set to OFF in /etc/php.ini, and it is not set to ON in any php.ini files, any files in /etc/php.d, or in any .htaccess files. So what could be setting it to ON between /etc/php.ini and /var/ What I mean by "between" is that if I set it to OFF in /var/ it is OFF, but if I don't, it is ON, even though /etc/php.ini explicitly sets it to OFF. This question is true for other settings, too, like upload_max_filesize, which is 8M in /etc/php.ini but 2M in phpinfo() unless I set it to 8M again in /var/ Also session.gc_maxlifetime is shorter in reality than the setting in /etc/php.ini, IIRC.

Ah, yes, webmin! That's another story. I'm new to VPS management (I loved Unix back in the 80's but I've forgotten most of what I knew). From shared-server experience I'm somewhat accustomed to cPanel and Plesk, but the hoster I chose for this VPS only offered Plesk and it conflicted with the structure I needed, so I went vanilla. When I was setting it up and adding the tools I needed, I also installed webmin (this all happened about a year ago). But it seemed that most of the things I needed to administer weren't in webmin, and each time I tried to use it I would search and search for something, decide it isn't there, and go back to SSH (while studying the internet for syntax to do whatever on the command line). Lately I haven't even bothered trying webmin - I just go straight to SSH, even though I'm far from proficient in that either. I probably need a course in webmin, because many people think it's great - perhaps I just didn't get it set up right or something. Off the top of my head, PHP, MySQL, postfix, and dovecot come to mind as things I can't configure in Webmin, but there are probably others.
 
webmin can manage and configure php, mysql, postfix and dovecot just fine. but if you're ok doing it the vanilla way then that's got to be better than using an abstraction layer/helper like webmin/cPanel etc. I like webmin for setting up apache servers and virtual hosts because it doesn't get in the way like cPanel and Plesk. it's much lighter weight, so if you do change something by hand in the config files, webmin doesn't get upset.

now to get back to your conundrum, I fear it is very simple to explain but perhaps not what you want to hear. If a setting is not expressly set in a loaded php.ini or local htaccess or httpd file, php sets it to a default value.

Although magic_quotes_gpc is deprecated and has been removed in php 5.4, the default value for magic_quotes_gpc remains 1 (ON), the default value for magic_quotes_runtime() is zero (OFF).

Likewise the default value for upload_max_filesize is "2M".

so it looks like your global config file is not getting loaded from /etc/php.ini. and the explanation for this (I think) is that php does not read _ALL_ configuration files that it finds in the hierarchy, but stops at the most granular level. so if it finds a local php.ini it reads that and stops.

if you want a single global set of settings and then local directory level differentiation, and you use apache, then the easiest method is to store php.ini in the master configuration location (/etc/php.ini) and use .htaccess files locally. But if you are using php 5.3 then you can also use php.ini style declarations in local directories BUT the files must be called
Code:
.user.ini
and then you must add a line to the master file
Code:
user_ini.filename = .user.ini

and the last alternative is to use a HOST section in your master php.ini file.
Code:
[HOST=mysubdomain.mydomain.com]
;add php directives here

you can do something similar with [PATH] too. bear in mind these work only on CGI/FCGI implementations
 
jpadie said:
webmin can manage and configure php, mysql, postfix and dovecot just fine.
That's what I assumed, but... Tutorial-like blogs and such just say stuff like (real quote): "You now want to go over to Servers > Postfix Mail Server..." Sure! On mine there is no such thing. Do I have to tell webmin that I have Postfix somehow?

jpadie said:
but if you're ok doing it the vanilla way then that's got to be better than using an abstraction layer/helper like webmin/cPanel etc.
I'm not really ok - since I'm not a Linux admin every day, I forget stuff and have to look it up all the time. I currently have some weird problem with either dovecot or postfix ever since a mysterious time hiccup (the system time leaped forward several hours and then back again, and as a defense mechanism dovecot shut itself down - even though I restarted it, now I can't authenticate anymore), and I'm waiting on a Linux guru friend to help me fix it (he lives on the other side of the world, but I trust him with my login), but he hasn't had time to look at it. My life is like that - I'm spread thin enough that I'm not really good at anything anymore. [3eyes]

jpadie said:
so if it finds a local php.ini it reads that and stops.
I don't presume to be wiser than the developers of PHP, but that doesn't seem logical to me, because a local copy is likely to only have a couple of settings. But it is what it is - at least I know now that it works that way.

After moving the more "local" php.ini files out of the way, indeed it started reading /etc/php.ini. Then I proceeded to try the different local file techniques in the order you wrote them.

(1) First I put .htaccess files with "php_flag..." commands in strategic places - that had no effect.

(2) Then I uncommented "user_ini.filename = .user.ini" in /etc/php.ini and put .user.ini files in the same strategic places. That worked for /var/ - yea!

But for my kizunadb.com client directories, it doesn't work to put a .user.ini file in /var/ even though a php.ini file gets read there. Where a .user.ini file does work is where the code actually is: /var/ (and /var/ But that doesn't help me, because what I need to specify is unique to each client:
Code:
open_basedir = /var/www/clientname/:/var/www/kizunadb/codebase/:/tmp/

(3) So I moved on to your "last alternative". I added the following code to the bottom of /etc/php.ini:
Code:
[HOST=dev.kizunadb.com]
open_basedir = /var/www/dev/:/var/www/kizunadb/dev/:/tmp/
That caused a more bizarre result:
Fatal error: Call to undefined function mysql_connect() in /var/ on line 207
In fact, I get that error even if the open_basedir line is commented out - if just the line "[HOST=dev.kizunadb.com]" is in effect, it fails. That function call is the third line of actual code run - first there are 200 lines of function definitions, then an explode(), then an include(), and then the mysql_connect() that fails.
 
I looked around Webmin some more. Servers contained the same list of 9 items, only three of which I even use (Apache, SSH, and Vsftpd). But then, for the first time, I noticed the section called "Un-used Modules". I don't remember ever noticing it before - its title is gray, so perhaps I thought it was disabled, or perhaps I ignored it because I was looking for things that were indeed used. But just now I looked in it, and voila! It contains about 40 items, including all the things I wish I had! I don't know how to get them to move to the Servers area (and perhaps move some truly un-used items from Servers to Un-used), but at least I finally found them - perhaps there is hope for Webmin in my life yet.

Looking forward to your insight on my main question.
 
On the web in side you need to install and enable the modules. I can't remember the exact process but it's just clicking links in the add modules section. I will pOst some screenshots if you need.
I will also look into the odd reports you have on user.ini. Can you confirm that all the local ghosts are using fcgi and for sure are not using sapi? For htaccess you need to restart the web server after each change of course.
 
I figured out the Webmin thing - there is a Refresh Modules function, which apparently doesn't work for everyone (a lot of complaints out there), but it worked for me.

jpadie said:
Can you confirm that all the local ghosts are using fcgi...
That gave me a good laugh, because I have been referring to this problem as my server being haunted! Anyway, as for the question, yes, phpinfo() says "Server API: CGI/FastCGI" for all of them.

I didn't realize that I needed to restart the web server for an .htaccess in a subdirectory, so perhaps that's why that technique didn't work when I tried it. I don't care whether I use .htaccess or .user.ini, but I think the problem in either case is that the document root for all the client subdomains is the same place: /var/ which means that I can't assign different open_basedir values. I held out some hope that since php.ini file is sought in the ScriptAlias directory (e.g. /var/ perhaps .user.ini might also be sought there, but it doesn't seem to be so. So it would appear that a [HOST...] directive is the only way to differentiate between the subdomains without everyone having their own exhaustive php.ini file.

I've taken one of my phpinfo() calls out from behind my authentication protection, so you can look for yourself (I'll hide it again later):
Whatever works for this subdomain will work for the others, so hopefully this information will reveal a clue.
 
ah. i hadn't grasped the docroot issue from your previous posts. reading too fast on s small screen. sorry.

anyway, yes - I would see that as causing distinct problems if you wanted a different htaccess per host. You could still use [HOST] sections in a .user.ini file in that directory (at least I cannot find anything to say that you shouldn't/can't)

there are web reports of plesk causing difficulties with fCGI and local htaccess files containing php directives. and of course even without plesk, this is the case and i was thick not to point it out y'day. the htaccess method is primarily for SAPI implementations. in (F)CGI mode php is run essentially as a command line app and not as an apache module, so apache directives are not as relevant.

There are exceptions to this rule with variant flavours of FCGI and there are extensions that will allow htaccess to be used.

but .user.ini files should be fine (if you are able to separate on a per dir basis) or using HOST sections on either the .user.ini or the main php.ini should be ok. bear in mind that .user.ini files are cached on a default 5 minute basis. when you're debugging/changing you might want to set an explicitly low ttl in php.ini.
Code:
user_ini.cache_ttl = 10 //ten seconds

the .user.ini is looked for in the directory of the requested php script and then recursively sought until $_SERVER['DOCUMENT_ROOT'] is found (unless a .user.ini is found earlier).

I cannot think at the moment why adding a [HOST] section has killed mysql. I'll have a longer think about that.
 
Now that I have commented out my authentication code in phpinfo.php, I can see the config values even when regular PHP code (like connecting to databases) doesn't work. I have determined the following:
[ul]
[li]Putting a [HOST] section in php.ini (either /etc/php.ini or /var/ whichever is read) does actually set the value - if the subdomain matches, I can see the effect in phpinfo().[/li]
[li]mysql_connect (and who knows what other PHP functions) is still undefined if the php.ini file contains [HOST] (any [HOST], even if the subdomain name isn't the same).[/li]
[li][HOST] sections in .user.ini are ignored - commands above that line are processed, but nothing below it, even when the subdomain matches.[/li]
[li][HOST] sections in .user.ini do not cause functions to crash - but since they don't actually do anything, that's not much consolation.[/li]
[/ul]
The priority of where a value comes from if it is set in multiple places is:
[ol 1]
[li]Directive in matching [HOST] section in php.ini[/li]
[li]General directive in .user.ini[/li]
[li]General directive in php.ini[/li]
[/ol]
So, with that information, are there any new ideas that come to mind? It's frustrating that Google ignores punctuation and case, because I can't search for "[HOST=", and with almost everyone's mysql_connect call having "$host" in it, I can't find anything relevent.

As an aside, I discovered that there are some directives in /etc/php.ini that are throwing me curveballs when I move the subdomain-specific php.ini file "out of the way", and it's taking a bit of research to determine what PHP was doing when there was "no value" for those things. The first two I have run into are:
[ul]
[li]session.save_path - /etc/php.ini sets it to /var/lib/php/session/, and even the comments say the default is /var/lib/php/session/, but empirical evidence indicates that when no value is set, /tmp/ is used. So I set that one explicitly in .user.ini so that my sessions would function again.[/li]
[li]error_reporting - the default when there is not explicit setting is E_ALL & ~E_NOTICES, but /etc/php.ini sets it to E_ALL & ~E_DEPRECATED, so suddenly I was getting all kinds of complaints about unset variables and such that I had never seen before. (I like that, though, so I think I'll keep that one and fix my code instead!)[/li]
[/ul]
I'm sure there are lots more - at some point I'll have to do a before/after diff on phpinfo() and check one by one to see what I need to "fix" with commands in .user.ini. (Yeah, I could edit /etc/php.ini instead, but I'm assuming those settings are normally good baseline starting values, so I'd rather meddle locally.)
 
just to check ... is the host section the last thing in php.ini?
 
Hey, jpadie - can you continue to help with this? After I answered your last question, I forgot about this whole thing for a while (got caught up in working on other projects), but now I'm running into this problem again.

At the moment, it's even a little more mysterious. In my development subdomain of the single-codebase app, I want to see syntax errors (of course!), but I'm not seeing them, even though the two related settings I know of look okay in phpinfo():
Code:
Directive         Local Value   Master Value
display_errors    On            On
error_reporting   30711         -1
I tried a variety of settings for error_reporting, but to no avail. Do you know what other things need to be set a certain way in order to get errors to show? (And any more thoughts on my original conundrum are also appreciated.)
 
Oops! Never mind on the error reporting question - the problem was in my code (a mistake in my code was actually causing no output, not a secret error). But the original question is still out there, if you have any more insight.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top