require_once 'prepend.inc'; commonHeader("Frequently Asked Questions"); ?>
This is a list of Frequently Asked Questions about PHP and their answers.
echo hdelim(); ?>
A nice introduction to PHP by Stig Sæther Bakken can be found here on the Zend website.PHP is an HTML-embedded scripting language. Much of its syntax is borrowed from C, Java and Perl with a couple of unique PHP-specific features thrown in. The goal of the language is to allow web developers to write dynamically generated pages quickly.
php-general-subscribe@lists.php.net. You don't need to include
anything special in the subject or body of the message.
To unsubscribe, send mail to php-general-unsubscribe@lists.php.net.
joeblow@example.com,
you can send your subscription request to
php-general-subscribe-joeblow=example.com@lists.php.net,
or your unsubscription request to
php-general-unsubscribe-joeblow=example.com@lists.php.net.
Before you post to the list please have a look in this FAQ and the manual to see if you can find the help there. If there is nothing to be found there try out the mailing list archives (see above). If you're having problem with installing or configuring PHP please read through all included documentation and README's. If you still can't find any information that helps you out you're more than welcome to use the mailing list.
This goes for any other problem as well. You have to include information on what you have done, where you got stuck, what you're trying to do and, if applicable, exact error messages. If you're having problems with your source code you need to include the part of the code that isn't working. Do not include more code than necessary though! It makes the post hard to read and a lot of people might just skip it all together because of this. If you're unsure about how much information to include in the mail it's better that you include to much than to little.
Another important thing to remember is to summarize your problem on the subject line. A subject like "HELP MEEEE!!!" or "What is the problem here?" will be ignored by the majority of the readers.
On Unix machines, you can use the Sybase-CT driver to access Microsoft SQL Servers because they are (at least mostly) protocol-compatible. Sybase has made a free version of the necessary libraries for Linux systems. For other Unix operating systems, you need to contact Sybase for the correct libraries. Also see the answer to the next question - 4.2.
If you are running PHP on a Unix box and want to talk to MS-Access on a Windows box you will need Unix ODBC drivers. OpenLink Software has Unix-based ODBC drivers that can do this. There is a free pilot program where you can download an evaluation copy that doesn't expire and prices start at $675 for the commercial supported version.
Another alternative is to use an SQL server that has Windows ODBC drivers and use that to store the data, which you can then access from Microsoft Access (using ODBC) and PHP (using the built-in drivers), or to use an intermediary file format that Access and PHP both understand, such as flat-files or dBase databases. On this point Tim Hayes from OpenLink software writes:
Using another database as an intermediary is not a good idea, when you can use ODBC from PHP straight to your database - i.e. with OpenLink's drivers. If you do need to use an intermediary file format, OpenLink have now released Virtuoso (a virtual database engine) for NT, Linux and other unix platforms. Please visit our website for a free download.
One option that has proven successful is to use MySQL and its MyODBC drivers on Windows and synchronizing the databases. Steve Lawrence writes:
Tips and Tricks: - You can construct your tables in access and export them to MySQL, then link them back in. That makes table creation quick.
- Install MySQL on your platform according to instructions with MySQL. Latest available from www.mysql.org (get it from your mirror!). No special configuration required except when you set up a database, and configure the user account, you should put % in the host field, or the host name of the Windows computer you wish to access MySQL with. Make a note of your server name, username, and password.
- Download the MyODBC for Windows driver from the MySQL site. Latest release is myodbc-2_50_19-win95.zip (NT available too, as well as source code). Install it on your Windows machine. You can test the operation with the utilities included with this program.
- Create a user or system dsn in your ODBC administrator, located in the control panel. Make up a dsn name, enter your hostname, user name, password, port, etc for you MySQL database configured in step 1.
- Install Access with a full install, this makes sure you get the proper add-ins.. at the least you will need ODBC support and the linked table manager.
- Now the fun part! Create a new access database. In the table window right click and select Link Tables, or under the file menu option, select Get External Data and then Link Tables. When the file browser box comes up, select files of type: ODBC. Select System dsn and the name of your dsn created in step 3. Select the table to link, press ok, and presto! you can now open the table and add/delete/edit data on your MySQL server! You can also build queries, import/export tables to MySQL, build forms and reports, etc.
- When creating tables in access, you must have a primary key defined in order to have write access to the table in access. Make sure you create a primary key in MySQL before linking in access.
- If you change a table in MySQL, you have to re-link it in access. Go to tools>add-ins>linked table manager, cruise to your ODBC DSN, and select the table to re-link from there. you can also move your dsn source around there, just hit the always prompt for new location checkbox before pressing ok.
People who aren't thoroughly familiar with the way web servers work and distribute the load may mistake persistent connects for what they're not. In particular, they do not give you an ability to open 'user sessions' on the same SQL link, they do not give you an ability to build up a transaction efficently, and they don't do a whole lot of other things. In fact, to be extremely clear about the subject, persistent connections don't give you any functionality that wasn't possible with their non-persistent brothers.
Why?
This has to do with the way web servers work. There are three ways in which your web server can utilize PHP to generate web pages.
The first method is to use PHP as a CGI "wrapper". When run this way, an instance of the PHP interpreter is created and destroyed for every page request (for a PHP page) to your web server. Because it is destroyed after every request, any resources that it acquires (such as a link to an SQL database server) are closed when it is destroyed. In this case, you do not gain anything from trying to use persistent connections -- they simply don't persist.
The second, and most popular, method is to run PHP as a module in a multiprocess web server, which currently only includes Apache. A multiprocess server typically has one process (the parent) which coordinates a set of processes (its children) who actually do the work of serving up web pages. When each request comes in from a a client, it is handed off to one of the children that is not already serving another client. This means that when the same client makes a second request to the server, it may be serviced by a different child process than the first time. What a persistent connection does for you in this case it make it so each child process only needs to connect to your SQL server the first time that it serves a page that makes us of such a connection. When another page then requires a connection to the SQL server, it can reuse the connection that child established earlier.
The last method is to use PHP as a plug-in for a multithreaded web server. Currently this is only theoretical -- PHP does not yet work as a plug-in for any multithreaded web servers. Work is progressing on support for ISAPI, WSAPI, and NSAPI (on Windows), which will all allow PHP to be used as a plug-in on multithreaded servers like Netscape FastTrack, Microsoft's Internet Information Server (IIS), and O'Reilly's WebSite Pro. When this happens, the behavior will be essentially the same as for the multiprocess model described before.
If persistent connections don't have any added functionality, what are they good for?
The answer here is extremely simple -- efficiency. Persistent connections are good if the overhead to create a link to your SQL server is high. Whether or not this overhead is really high depends on many factors. Like, what kind of database it is, whether or not it sits on the same computer on which your web server sits, how loaded the machine the SQL server sits on is and so forth. The bottom line is that if that connection overhead is high, persistent connections help you considerably. They cause the child process to simply connect only once for its entire lifespan, instead of every time it processes a page that requires connecting to the SQL server. This means that for every child that opened a persistent connection will have its own open persistent connection to the server. For example, if you had 20 different child processes that ran a script that made a persistent connection to your SQL server, you'd have 20 different connections to the SQL server, one from each child.
An important summary. Persistent connections were designed to have one-to-one mapping to regular connections. That means that you should always be able to replace persistent connections with non-persistent connections, and it won't change the way your script behaves. It may (and probably will) change the efficiency of the script, but not its behavior!
Most likely what has happened is, PHP4 was compiled with the '--with-mysql' option, without specifying the path to mysql. This means PHP is using its built-in mysql client library. If your system is running applications, such as php3 as a concurrent Apache module, or auth-mysql, that use other versions of mysql clients, then there is a conflict between the two differing versions of those clients.
Recompiling php4, and adding the path to mysql to the flag, '--with-mysql=/your/path/to/mysql' usually solves the problem.
If your MySQL libs are linked against pthreads this will happen. Check using ldd. If they are, grab the MySQL tarball and compile from source, or recompile from the source rpm and remove the switch in the spec file that turns on the threaded client code. Either of these suggestions will fix this. Then recompile PHP with the new mysql libs.
To install PHP, follow the instructions in the INSTALL file located in the distribution. Windows 95 and NT users should also read the README.WIN32 file. There are also some helpful hints for Windows users here.
If you are trying to install PHP for use with Netscape's web server on Unix see: http://www.webgenx.com/php/phpnes.php3
--with-config-file-path=/etc
And then you would copy php3.ini-dist from the distribution to /etc/php3.ini and
edit it to make any local changes you want.
# Extra Modules AddModule mod_php.c AddModule mod_php3.c AddModule mod_perl.c # Extra Modules LoadModule php_module modules/mod_php.so LoadModule php3_module modules/libphp3.so /* for PHP 3 */ LoadModule php4_module modules/libphp4.so /* for PHP 4 */ LoadModule perl_module modules/libperl.so
AddType application/x-httpd-php3 .php3 /* for PHP 3 */ AddType application/x-httpd-php .php /* for PHP 4 */... to the global properties, or to the properties of the VirtualDomain you want to have PHP support added to.
Currently the RPM packagers are setting up the RPMS to install without database support to simplify installations and because RPMS use /usr/ instead of the standard /usr/local/ directory for files. You need to tell the RPM spec file which databases to support and the location of the top-level of your database server.
This example will explain the process of adding support for the popular MySQL database server, using the mod installation for Apache.
Of course all of this information can be adjusted for any database server that PHP supports. We will assume you installed MySQL and Apache completely with RPMS for this example as well.
rpm -e mod_php3rpm -Uvh mod_php3-3.0.5-2.src.rpm--with-mysql=/usr \
./configure --prefix=/usr \
--with-apxs=/usr/sbin/apxs \
--with-config-file-path=/usr/lib \
--enable-debug=no \
--enable-safe-mode \
--with-exec-dir=/usr/bin \
--with-mysql=/usr \
--with-system-regex
rpm -bb /usr/src/redhat/SPECS/mod_php3.spec rpm -ivh /usr/src/redhat/RPMS/i386/mod_php3-3.0.5-2.i386.rpm
./buildconf in the top-level directory after getting
the sources from the CVS server. (Also, unless you run configure
with the --enable-maintainer-mode option, the
configure script will not automatically get rebuilt when the
configure.in file is updated, so you should make sure to do that
manually when you notice configure.in has changed. One symptom
of this is finding things like @VARIABLE@ in your Makefile after
configure or config.status is run.)
--with-apache=/path/to/apache'
and not '--with-apache=/path/to/apache/src'.
CPPFLAGS=-I/path/to/include LDFLAGS=-L/path/to/library ./configure
If you're using a csh-variant for your login shell (why?), it would be:
env CPPFLAGS=-I/path/to/include LDFLAGS=-L/path/to/library ./configure
cp *.o functions" and then
re-running 'make' to see if that helps. If it does, you should really
upgrade to a recent version of GNU make.
If you're linking with Apache 1.2.x, did you remember to add the appropriate information to the EXTRA_LIBS line of the Configuration file and re-rerun Apache's Configure script? See the INSTALL file that comes with the distribution for more information.
Some people have also reported that they had to add '-ldl' immediately following 'libphp3.a' when linking with Apache.
This is actually quite easy. Follow these steps carefully:
This means that the PHP module is not getting invoked for some reason. Three things to check before asking for further help:
my $CFG_CFLAGS_SHLIB = ' '; # substituted via Makefile.tmpl my $CFG_LD_SHLIB = ' '; # substituted via Makefile.tmpl my $CFG_LDFLAGS_SHLIB = ' '; # substituted via Makefile.tmplIf this is what you see, you have found your problem. Change these lines to say:
my $CFG_CFLAGS_SHLIB = '-fpic -DSHARED_MODULE'; # substituted via Makefile.tmpl my $CFG_LD_SHLIB = 'gcc'; # substituted via Makefile.tmpl my $CFG_LDFLAGS_SHLIB = q(-shared);# substituted via Makefile.tmplThe second possible problem should only be an issue on RedHat-6.1/6.2. The apxs script RedHat ships is broken. Look for this line:
my $CFG_LIBEXECDIR = 'modules'; # substituted via APACI installIf you see the above line, change it to this:
my $CFG_LIBEXECDIR = '/usr/lib/apache'; # substituted via APACI installLast, if you reconfigure/reinstall Apache, add a 'make clean' to the process after './configure' and before 'make'.
microtime.c: In function `php_if_getrusage':
microtime.c:94: storage size of `usg' isn't known
microtime.c:97: `RUSAGE_SELF' undeclared (first use in this function)
microtime.c:97: (Each undeclared identifier is reported only once
microtime.c:97: for each function it appears in.)
microtime.c:103: `RUSAGE_CHILDREN' undeclared (first use in this function)
make[3]: *** [microtime.lo] Error 1
make[3]: Leaving directory `/home/master/php-4.0.1/ext/standard'
make[2]: *** [all-recursive] Error 1
make[2]: Leaving directory `/home/master/php-4.0.1/ext/standard'
make[1]: *** [all-recursive] Error 1
make[1]: Leaving directory `/home/master/php-4.0.1/ext'
make: *** [all-recursive] Error 1
Your system is broken. You need to fix your /usr/include files either by making sure
your /usr/include/linux symlink is pointing to the right place in your kernel sources or
by installing a glibc-devel package that matches your glibc. This has absolutely nothing
to do with PHP. To prove this to yourself, try this simple test:
$ cat >test.c <<X
#include <sys/resource.h>
X
$ gcc -E test.c >/dev/null
If that spews out errors, you know your include files are messed up.
while (list($var, $value) = each($HTTP_POST_VARS)) {
echo "$var = $value<br>\n";
}
The ereg_replace magic you're looking for, however, is simply:
$escaped = ereg_replace("'", "\\'", $input);
function myfunc($argument) {
echo $argument + 10;
}
$variable = 10;
echo "myfunc($variable) = " . myfunc($variable);
What's going on?
<PRE> 1 <?echo $result[1];?> 2 <?echo $result[2];?>
Why does PHP do this? Because when formatting normal HTML, this usually makes your life easier because you don't want that newline, but you'd have to create extremely long lines or otherwise make the raw page source unreadable to achieve that effect.
$headers = getallheaders();
for(reset($headers); $key = key($headers); next($headers)) {
echo "headers[$key] = ".$headers[$key]."<br>\n";
}
$result = mysql_query("select * from tables_priv");
if(!$result) {
echo mysql_error();
exit;
}
or:
$result = mysql_query("select * from tables_priv")
or die("Bad query: ".mysql_error());
<input type="image" SRC="image.gif" NAME="foo">When the user clicks somewhere on the image, the accompanying form will be transmitted to the server with two additional variables: foo.x and foo.y.
Because $foo.x and $foo.y are invalid variable names in PHP, they are automagically converted to $foo_x and $foo_y. That is, the periods are replaced with underscores.
<SELECT NAME="var" MULTIPLE>Each selected option will arrive at the action handler as:
var=option1 var=option2 var=option3Each option will overwrite the contents of the previous $var variable. The solution is to use PHP's non-indexed array feature. The following should be used:
<SELECT NAME="var[]" MULTIPLE>This tells PHP to treat var as an array and each assignment of a value to var[] adds an item to the array. The first item becomes $var[0], the next $var[1], etc. The count() function can be used to determine how many options were selected, and the sort() function can be used to sort the option array if necessary.
Note that if you are using JavaScript the [] on the element name might cause you problems when you try to refer to the element by name. Use it's numerical form element id instead, or enclose the variable name in single quotes and use that as the index to the elements array, for example:
variable = documents.forms[0].elements['var[]'];
<input name="MyArray[]">
<input name="MyArray[]">
<input name="MyArray[]">
<input name="MyArray[]">
Notice the square brackets after the variable name, that's what
makes it an array. You can group the elements into different arrays
by assigning the same name to different elements:
<input name="MyArray[]">
<input name="MyArray[]">
<input name="MyOtherArray[]">
<input name="MyOtherArray[]">
This produces two arrays, MyArray and MyOtherArray, that gets sent
to the PHP script.
Note that you must not use indices with arrays in HTML! The array gets filled in the order the elements appear in the form. For functions you can use to process these arrays once you get them into your scripts, please see the Arrays section in the manual.
A great summary by Michael J Sheldon on this topic has been posted to the PHP mailing list. A copy can be found here.
If your script uses the regular expression functions (ereg()
and friends), you should make sure that you compiled PHP and
Apache with the same regular expression package. (This should
happen automatically with PHP and Apache 1.3.x)
global $DOCUMENT_ROOT;", for example) or by using
the global variable array (ie, "$GLOBALS["DOCUMENT_ROOT"]".
All the code for previous versions of the website is still available through CVS. Specifically, the last version of shared.inc (that had all the Javascript and DHTML to do the popups) is available print_link("http://cvsweb.php.net/viewcvs.cgi/phpweb/include/shared.inc?rev=1.123&content-type=text/vnd.viewcvs-markup", "here"); ?>.
This FAQ was originally written by Jim Winstead. It is currently maintained by the PHP Documentation Team.
commonFooter(); ?>