How do I add a directory to the perl include path from an apache config file? - apache

I am on centos using apache and mod_perl 2, and I have a PerlRequire directive in my apache config file to specify my mod_perl startup file:
PerlRequire startup.pl
However, when I try to start apache, mod_perl cannot find startup.pl in its perl include path. The apache error log says:
[error] Can't locate startup.pl in #INC (#INC contains: /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 . /etc/httpd) at (eval 2) line 1.
The mod_perl 2 documentation says that there is that there is a PerlSetEnv directive that can be used to set an environment variable,
http://perl.apache.org/docs/2.0/user/config/config.html#C_PerlSetEnv_ and the PERL5LIB environment variable can be set for this purpose, as explained here: http://learn.perl.org/faq/perlfaq8.html#How_do_I_add_the_dir
But if the PERL5LIB variable has already been set, then I do not want to clobber the previous setting, I would instead want to add another directory to it. What directive can I use in my apache config file to add a directory to the perl include path (#INC) without clobbering its previous contents?
EDIT: The answer by #jm666 to use "PerlSwitches -I/some/other/path" in the apache config sounds like the right answer, though another possibility is to use the full path of startup.pl in my PerlRequire directive. However, the other suggested answer to do it from startup.pl will not work, because it is startup.pl that mod_perl cannot find.

You can do it from your startup.pl like:
use lib qw(/some/other/path);
From the doc for the lib pragma
It is typically used to add extra directories to perl's search path so
that later use or require statements will find modules which are not
located on perl's default search path.
The parameters to use lib are added to the start of the perl search
path. Saying
use lib LIST;
is almost the same as saying
BEGIN { unshift(#INC, LIST) }
Or, you can do this from the httpd.conf, with the
PerlSwitches -I/some/other/path

Related

Php extension not loaded

Using a .user.ini file with extension=geoip.so (or mysqli.so) I'm trying unsuccessfully to load the relevant module: in the phpinfo() page of Php 7.1 (or even Php5.4) the module is never shown.
1) The .user.ini file is working correctly because I'm able to modify the variable memory_limit.
2) The phpinfo() function correctly shows the extension_dir folder containing .so extensions that I want to load (in the php.ini file this variable is not present, however).
3) The php error log contains no message.
Every suggestion is welcome.
The .user.ini files can only set certain PHP ini settings. It just so happens that the extension setting is not one of them. In fact, according to the manual, the extension setting is only valid in the core php.ini file. So put the extension=geoip.so in your main php.ini file.
As a side note: I use Ubuntu/Debian for most of what I do with PHP. The standard PHP distro that is available through the Debian package archives has extra code compiled into it that allows for a distributed configuration. The way this works is the SAPI module scans a conf.d directory and includes any ini files. Typically when you package an external PHP extension for Debian (which I might add is a pain - I've done it for my own extensions) you include a little ini file that includes the extension (e.g. extension=myext.so). The package installs it in the distributed config directory and it is included into the php.ini file when PHP spins up. Perhaps you meant to install a Debian-based config like this?
Another side note: Since you are probably using a CGI SAPI and might want different sites to load different modules (exclusively), you could perhaps look into getting the Web server to point the CGI PHP at a different php.ini file. I'm just presuming you want to achieve something like this. However loading modules for certain directories using .user.ini files is just not possible.
Try disable or configure selinux. Check selinux audit log.

PerlLoadModule can't find module

My workplace has a shared development environment, and I am localing a copy of it.
In the Apache configuration is the following directive:
PerlLoadModule MSC::Framework::R0028::Handler::Init::Database
When I start Apache, it gives me this error:
Can't locate MSC/Framework/R0028/Handler/Init/Database.pm in #INC (#INC contains ... )
I have numerous copies of Database.pm, but I'm not sure how in the Apache config the path to this file is specified.
How can I hook this up?
Has nothing to do with Apache. Perl can't find the specified module. Perl looks at the #INC variable for a search path. It's built from hardcoded paths, from command-line option -I (not applicable here) and from env var PERL5LIB, though it can be modified by code too.
#INC, perlrun
Tips from the mod_perl docs

Declaring global variable with php.ini

Is it possible to keep variables in php.ini file. Like that we do with the web.config in .net. I like to keep a flag type variable in the php.ini and use it to different projects.
It's not possible to set user-level variables within a plain php.ini file (or the .htaccess equivilents). There are some PECL modules that do allow that, such as hidef (http://pecl.php.net/package/hidef) - though these would need to be installed on every installation you use.
Including (or pre-including) a file with auto_prepend_file is quite possible - though that would be on every PHP request.
What is frequently done is setting an environment variable as part of the webserver process, which can be read from PHP. In Apache this is quite easy, with the SetEnv module.
SetEnv PRODUCTION_SERVER 1
And accessing it in PHP:
if ($_ENV['PRODUCTION_SERVER']) {...} // or getenv('PRODUCTION_SERVER')
Have you looked at get_cfg_var()?
I needed to do something similar, and this was able to do it for me.
Nope.
You could use the auto_prepend_file directive to automatically include a file that said, although as it uses the include_path, you'd need to specify the full path.
However, it's probably more transparent just to explicitly include/require the relevant file.
One technique that I have found useful for passing a limited number of global variables to a bootstrap script is to take advantage of the SetEnv directive in an .htaccess file. The advantage is that the variable you set will be made available to any script in that directory, plus any scripts in child directories under it.
You could use a SetEnv varibale with the location of a configuration file, such as:
in .htaccess:
SetEnv init_path /home/hendepher/TestApp/init/init.php
In your .php scipt:
<?php
if(!getenv('init_path')) throw new Exception('Must set init_path in .htaccess');
require_once getenv('init_path');
.
.
.
?>
If you have a test directory that requires different initialization o global variables, simply add another .htaccess file in your test directory:
SetEnv init_path /home/hendepher/TestApp/init/testing_init.php
Doing it this way, as opposed to using the 'auto_prepend_file' directive, is that your global configuration script is not run by all the php applications on your server: some may not need it.
The accepted answere also worked for me, with one change.
I didn't test this on earlier versions, but in my environment (php 5.4.22) this doesn't show up in $_ENV, but rather in $_SERVER.
In my .htacess file:
SetEnv PRODUCTION_SERVER 0.
My php code:
$production="PRODUCTION";
if (!isset($_SERVER['PRODUCTION_SERVER']) || $_SERVER['PRODUCTION_SERVER'] != 1){
$production="DEVELOPMENT";
}
I don't think that's a good place to store variables. php.ini is for storing configuration for PHP itself not your applications. You should consider putting the shared variables into a .inc file and including that instead.
Have you considered hidef?
Allow definition of user defined constants in simple ini files,
which are then processed like internal constants, without any
of the usual performance penalties.
Complementing #Ascherer answer, use get_cfg_var() to save custom variables in custom php.ini (variable created by you, not an official PHP ini directive). For example:
In php.ini: custom_variable = "abcde"
In any php script: get_cfg_var('custom_variable') returns abcde
I use this in in a small project in local dev. As I run the local server via php -S localhost:8000 -c php.ini (not running an Apache server locally), it's a good option to call some configuration constants. In production, these constants are set in .htaccess.

What can change the include_path between php.ini and a PHP file

I've inherited some code on a system that I didn't setup, and I'm running into a problem tracking down where the PHP include path is being set.
I have a php.ini file with the following include_path
include_path = ".:/usr/local/lib/php"
I have a PHP file in the webroot named test.php with the following phpinfo call
<?php
phpinfo();
When I take a look at the the phpinfo call, the local values for the include_path is being overridden
Local Value Master Value
include_path .;C:\Program Files\Apache Software Foundation\ .:/usr/local/lib/php
Apache2.2\pdc_forecasting\classes
Additionally, the php.ini files indicates no additional .ini files are being loaded
Configuration File (php.ini) Path /usr/local/lib
Loaded Configuration File /usr/local/lib/php.ini
Scan this dir for additional .ini files (none)
additional .ini files parsed (none)
So, my question is, what else in a standard PHP system (include some PEAR libraries) could be overriding the include_path between php.ini and actual php code being interpreted/executed.
Outisde of the PHP ways
ini_set( 'include_path', 'new/path' );
// or
set_include_path( 'new/path' );
Which could be loaded in a PHP file via auto_prepend_file, an .htaccess file can do do it as well
phpvalue include_path new/path
There are several reasons why you are getting there weird results.
include_path overridden somewhere in your php code. Check your code whether it contains set_include_path() call. With this function you can customise include path. If you want to retain current path just concatenate string . PATH_SEPARATOR . get_include_path()
include_path overridden in .htaccess file. Check if there are any php_value or php_flag directives adding dodgy paths
non-standard configuration file in php interpreter. It is very unlikely, however possible, that your php process has been started with custom php.ini file passed. Check your web server setup and/or php distribution to see what is the expected location of php.ini. Maybe you are looking at wrong one.
An .htaccess file or Apache's configuration (httpd.conf) could also be responsible.
Check for anything that looks like the following:
php_value include_path something
More information about that behavior here:
PHP: How to change configuration settings
The other option would be the use of ini_set() or set_include_path() somewhere, but considering that your test.php only contains phpinfo() (and assuming that test.php is called directly), I doubt that is your problem.

How to check where Apache is looking for a php.ini file?

I have a feeling that Apache is using a different php.ini file that the one I am editing. I make a change in my php.ini file, restart Apache, and the change doesn't take affect. So I don't know what to do anymore.
Any ideas?
Update: Found out it's using the right php.ini file...but I still don't know what to do!
To find the file that's being run by PHP, create a phpinfo file (just <?php phpinfo();?>) and look for the 'Configuration File (php.ini) Path' directive.
from the command line, run
php -i |grep "php.ini"
This will describe the location php is loading its ini file from. You can reconfigure the php.ini location by recompiling php.
The output from phpinfo() will contain this. When using PHP as an Apache module, it can be configured using PHPIniDir in httpd.conf (or similar).
To get the php.ini file which is being used by Apache you will probably have to add phpinfo() into a .php file and open it in the browser. As php -r "phpinfo();" | grep php.ini will outout the same as php --ini would. Which php.ini is used for the CLI.
Question for you, what platform are you running on unix or windows?
If it is unix based, check if your php.ini is residing in the same directory as /etc/httpd. Again, installation of apache can vary so check...or issue the command "find / -name php.ini -print" (without quotes) to see which one is it you are using
Ok. Since you said you have found the correct php.ini, sounds like something is missing when you edited the php.ini and reloaded apache. Look in the log directory /var/log/httpd for error_log and check to see if there was errors...that would be a start!