tags:

views:

95

answers:

4

Can anyone of you help me understand the behavior I get when visiting this page?

<html>

    <body>

    <?php
        $liendb = mysql_connect("localhost","","");

        mysql_select_db ("test");
        for($i = 0; $i < 418; ++$i)
        {
            echo("Any old text<br />");
        }


        $resultatSQL = mysql_query("SELECT uid FROM nombres ORDER BY uid");

        while($tab = mysql_fetch_array($resultatSQL, MYSQL_ASSOC))

        {
            echo("<p>".$tab['uid']."</p>");
            echo("<br />\n");

        }

        mysql_close();

    ?>

    </body>
</html>

I exported the mysql table this example is based on so that we can work on the same table.. Here it is:

-- phpMyAdmin SQL Dump
-- version 3.2.0.1
-- http://www.phpmyadmin.net
--
-- Servidor: localhost
-- Tiempo de generación: 06-01-2010 a las 21:49:50
-- Versión del servidor: 5.1.37
-- Versión de PHP: 5.3.0

SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";

--
-- Base de datos: `test`
--

-- --------------------------------------------------------

--
-- Estructura de tabla para la tabla `nombres`
--

CREATE TABLE IF NOT EXISTS `nombres` (
  `uid` int(10) unsigned NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (`uid`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=43 ;

--
-- Volcar la base de datos para la tabla `nombres`
--

INSERT INTO `nombres` (`uid`) VALUES
(1),
(2),
(3),
(4),
(5),
(6),
(7),
(8),
(9),
(10),
(11),
(12),
(13),
(14),
(15),
(16),
(17),
(18),
(19),
(20),
(21),
(22),
(23),
(24),
(25),
(26),
(27),
(28),
(29),
(30),
(31),
(32),
(33),
(34),
(35),
(36),
(37),
(38),
(39),
(40),
(41),
(42);

In theory, I believe this page should print 418 lines of "Any old text", and then print all entries of table "nombres", so numbers 1 to 42. In practice, it does. But if I change that magic number, 418, problems happen.

If I use a number smaller than 418, firefox offers to download the page instead of just showing it to me.. If I do download it, I get a blank file..

If I use a number larger than 418, I don't get all the entries to table "nombres". For example, when I use 419, I get only numbers 1 to 41. When I use 420, I get only numbers 1 to 40. And so on until 454, where I only get number 1. The rest of the page, everything following the numbers, is truncated, including the closing body and html tags.

If I use 455 or more, I don't get any numbers at all!

My questions:

Is anyone else able to reproduce this behavior? How could you explain this behavior?

The server I use is apache (actually xampp) I printed phpinfo() and asked firefox to save the resulting page.. Here it is, compressed. www.angelfire.com/planet/shawninder/phpinfo.zip

A: 

What webserver do you use? Apache? Are there any extesnions to PHP installed? Try putting flush() after echo to see whats happen. If you could show you phpinfo() it could help.

habicht
Apache, actually it's xampp. I edited this in my original question. I also added the result of phpinfo.. Where is it you suggest adding flush? The first echo or the second? or both?
Shawn
I added flush after every echo, it doesn't seem to change anything..
Shawn
A: 

Works OK for me. It seems to print all the expected lines of "Any old text" and also all numbers after that.

I imagine that it might be a web server or PHP misconfiguration, but I can't quite think where to begin with that.

Jeff
You say it works OK. Have you tried changing the number (418) to something else?
Shawn
Yup, works for all the numbers I tried. I tried a variety such as 1, 200, 1000, all are OK.
Jeff
A: 

I tried it and it all works as expected.

Only thing I noticed is that the page is around 8kB. Is there some magic configuration in your webserver (which webserver are you using?) which could be connected with an 8kB page size?

mopoke
I have no clue.. But I added the results of phpinfo in my original question, maybe you would recognize such a configuration?
Shawn
+1  A: 

Judging from your code, maybe the problems lies in the mysql connection. You should always check if the mysql connection is successfully or failed, before using it. Try to rewrite your code like this:

<html>
    <body>
    <?php
        //open connection
        $liendb = mysql_connect("localhost","","");
        if ( ! $liendb )
        {
          die('Could not connect: ' . mysql_error());
        }

        //select database
        $select_db = mysql_select_db ("test", $liendb);
        if ( ! $select_db )
        {
          die ("Failed to do select the database: ' . mysql_error());
        }

        //print 'magic' lines
        for($i = 0; $i < 418; ++$i)
        {
            echo("Any old text<br />");
        }

        //get table's content
        $resultatSQL = mysql_query("SELECT uid FROM nombres ORDER BY uid", $liendb);
        if ( ! $resultatSQL )
        {
          die('Invalid query: ' . mysql_error());
        }

        //process table content
        while($tab = mysql_fetch_array($resultatSQL, MYSQL_ASSOC))
        {
            echo("<p>".$tab['uid']."</p>");
            echo("<br />\n");
        }
        mysql_close($liendb);
    ?>
    </body>
</html>

With this code, if any error related with mysql connection happened, then you will got the error message, instead of it silently fail. Maybe it will make the php module in apache crash, so the process died prematurely and apache then send the incomplete page as a file to download, instead of displaying it as a web page.

Let me know the result in your computer.

Donny Kurnia
I tried your code and I get one warning: ---Warning: Unknown: 1 result set(s) not freed. Use mysql_free_result to free result sets which were requested using mysql_query() in Unknown on line 0--- But even better, the problem seems to have stopped! No matter how many useless lines I print, I get all the table entries! I don't exactly know which part of your code solved the problem, but I'll try to figure that out next. Thanks very much in any case! and btw, do you know what it means to free result sets?
Shawn
Well, after a couple of tests, I found out that the part of your code that solved my problem was adding $liendb in the mysql_close statement... Do you think you could explain this to me? Because frankly, I don't understand why this statement affects what happens earlier in the code...
Shawn
you could read the function definition and usage here: http://id2.php.net/manual/en/function.mysql-close.php Maybe without passing `$liendb`, the statement try to close all connection, that might cause the execution died prematurely, and apache serve the page as php file, not as web page. My guess that the php module in your xampp have bug, or maybe the php-mysql client. Upgrade to latest version might solve the problems.
Donny Kurnia