This may be a register_globals = on issue or url rewriting problem. I eliminated the url rewriting possibility by using basic php linking syntax. I tried several patches to emulate register_globals being on but to no avail. The site was functioning normally until last week when the php.ini file was updated. It is an Apache server with php 5.4.23.
Basically I have a catalog page which displays a list of works called from a mysql database. When the user clicks the link, it brings the user to the appropriate item page. The catalog list displays correctly but the links do not function anymore and there is not error displayed. It always links to the first item of the mysql request and not the link that is requested even though the url that is displayed is correct.
Here is the code to connect to the database:
<?php
$db = mysql_connect("localhost", "user", "pw");
mysql_select_db("database_name",$db);
$sqlNum = 'SELECT * FROM callejas ORDER BY engname ';
$sql = 'SELECT * FROM callejas ORDER BY engname LIMIT '.(($page-1)).",".(1);
$resultNum = mysql_query($sqlNum);
$numRows = mysql_num_rows($resultNum);
$sqlnext = 'SELECT * FROM callejas ORDER BY engname LIMIT ' .(($page)).",".(1);
$sqlpre = 'SELECT * FROM callejas ORDER BY engname LIMIT ' .(($page-2)).",".(1);
//sommaire
$req = 'SELECT * FROM callejas ORDER BY engname ';
$result = mysql_query($req);
$result1 = mysql_num_rows($result);
$milieu = $result1 / 2;
$mil = (int)$milieu ;
$left = 'SELECT * FROM callejas ORDER BY `engname` ASC LIMIT 0,'.($mil);
$right = 'SELECT * FROM callejas ORDER BY `engname` ASC LIMIT '.($mil).",".($result1);
?>
Here is part of the catalog.php file which functions correctly except for the link
<?
include ("connecttodatabase.php");
$i=1;
$j=0;
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1 /DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
</head>
<body>
<div align="right" id="left" style="position:absolute; width:200px; height:388px; z-index:42; left: 6px; top: 170px;" class="interline30">
<?
$leftres = mysql_query($left);
function StandardizeString($img)
{
$img = strtr($img,
'ŠŽšžŸÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÑÒÓÔÕÖØÙÚÛÜÝàáâãäåçèéêëìíîïñòóôõöøùúûüýÿ',
'SZszYAAAAAACEEEEIIIINOOOOOOUUUUYaaaaaaceeeeiiiinoooooouuuuyy' );
$img = preg_replace('/[\'"]/', '',$img); // Eliminate all quotes
$img = preg_replace('/[^a-zA-Z0-9]+/', '-', $img); // Remove all spaces
$img = trim($img, '_'); // Remove any leading or trailing underscored
// Return the result
return $img;
}
while(($myrow = mysql_fetch_array($leftres)))
{
$img= $myrow['engleg'] ;
$little = "".$myrow['little'];
$tittle = StandardizeString($img);
?>
<div align="center"
<?
echo "id=\"$i\"";
?>
style="position:absolute; width:153px; z-index:49; left: 207px;top:
<?
echo "$j px;"
?>
visibility: hidden;">
<?
echo "<img src= \"{$little}\" title= \"{$img}\" alt= \"{$img}\">";
?>
</div>
<?
echo "<p><a href='works.php?tittle=$tittle&page=$i'
$img</a></p>";
$i++;
$j = $j+30;
}
?>
</div>
</body>
I have not been able to see what is wrong. This code has functioned for several years and after reading about the differences between php 5.3 and 5.4 I don't see any code that is deprecated
but I do know that register_globals was on.
Hum...register_globals is DEPRECATED since PHP 5.3.0 and REMOVED in PHP 5.4"
Your problem lies certainly in this script : works.php
Please consider this quick and dirty fix : register_globals fix
The below lines in your code not closed. You can fix it by closing it with semi colon.
<?
echo "$j px;";
?>
also follow this SO answer to run your script like register global is enabled.
https://stackoverflow.com/a/16706242/817365
Related
over the last couple of days I've been working on a application that let's a user upload a image and store the image in my filesystem and the file path in my database. I'm almost done but i have come across a brick wall.
The image gets uploaded to my filesystem and the file path stored in my database just fine. put when i go to the page that displays the images. it returns them as
"broken images"
here's the code that is giving me trouble
<?php
error_reporting (E_ALL ^ E_NOTICE);
session_start();
$uname = $_SESSION['username'];
$userid = $_SESSION['id'];
?>
<!DOCTYPE html>
<html>
<head>
<title>OurFile's Page</title>
</head>
<body>
<?php
require("pdoconn.php");
//img_path is the column in my DB that holds the image URL.
$stmt = $conn->prepare("SELECT img_path FROM ourimages");
$stmt->execute();
while($result = $stmt->fetch(PDO::FETCH_BOTH))
{
echo '<br><img src="' . $result['img_path'] . '" />';
}
$conn = null;
?>
</body>
</html>
any help would be appropriated.
Thank you for your future responses
i edited the code. using ed and jay's suggestions...but its still
output the same result
You can't do this:
<img src="<?php echo $value; ?>" />
because you're using $value to loop over every column in the table. The src attribute needs to be a URL, but I'm guessing only one column in your ourimages table holds a URL. You're outputting an image for every column thanks to this:
$stmt = $conn->prepare("SELECT * FROM ourimages"); // gets every column
$stmt->execute();
$result = $stmt->fetch(PDO::FETCH_BOTH);
foreach ($result as $value) // uses every column
{
The simple fix is to change your SQL:
$stmt = $conn->prepare("SELECT whateverColumnHasTheURL FROM ourimages");
Then use that column like this:
<img src="<?php echo $result->whateverColumnHasTheURL; ?>" />
Or, you can use the SELECT * ..., but just use the one column in the <img> tag:
$stmt = $conn->prepare("SELECT * FROM ourimages");
$stmt->execute();
$result = $stmt->fetch(PDO::FETCH_BOTH);
echo "<br>";?> <img src="<?php echo $result->whateverColumnHasTheURL; ?>" /><?php
Note: If you're actually trying to loop over the rows, you need to put $stmt->fetch in a loop, as in while ($result = $stmt->fetch(PDO::FETCH_BOTH);) { echo... }
Using a foreach loop to output the results of the query is an interesting way of doing things. Most folks use a while loop like this:
while($result = $stmt->fetch(PDO::FETCH_BOTH))
{
echo '<br><img src="' . $result['column_with_image_path'] . '" />';
}
Since you're selecting all of the columns from your table you need to be specific about the identifier you use in the image tag.
I've been working with this one page forever using MAMP and I can't get the PHP to render. It must be something with getting the info from the table but I can't figure out what. I'm pretty sure I have everything lined up correctly.
For a while it was just sending me back jibberish and then nothing but eventually I got it render the HTML through localhost by switching the while loop to a do-while loop so that it would run through once. So the issue must be with the connection to MySQL I'm thinking, but I don't know what.
<?php
$product_id = $_GET['id'];
$link = mysqli_connect('localhost', 'root', 'root', 'legend');
$result = mysqli_query($link, "SELECT * FROM test WHERE id=" . $product_id . "'");
while($row = mysqli_fetch_array($result)) {
?>
<html>
<head>
</head>
<body>
<div>
<p>Name: <?php echo $row['unitOne']; ?></p>
<p>Box Quantity: <?php echo $row['unitTwo']; ?></p>
</div>
</body>
</html>
<?php
}
mysqli_close($link);
?>
Try to structure your code this way and please consider all the comments below your first post. I also recommend reading this article that will clarify what prepared statements and bound parameters are: http://www.w3schools.com/php/php_mysql_prepared_statements.asp
Remember to always construct your HTML markup correctly. There should never be more than one open and close tag for html, head and body. And if you do have more that can surely mess things up for you.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Cart</title>
</head>
<body>
<?php
$query = "SELECT * FROM products WHERE product_id = ?"; //for security we will be using prepared statements
$stmt = $link -> mysqli -> prepare($query); //$link contains your database connection
$stmt -> bind_param('i', $id); //$id contains a product id the "i" will define it as an integer
$stmt -> execute();
$result = $stmt -> fetch_result();
while($row = $result -> fetch_assoc()){ //loop out the results
echo '<div>';
echo '<p>Name: '.$row['unitOne'].'</p>';
echo '<p>Box Quantity: '.$row['unitTwo'].'</p>';
echo '</div>';
}
?>
</body>
</html>
Hi I'm using file_get_contents() to search an off site text file, which returns an array as follows:
$foo_data = file_get_contents('http://foo/data_csv.php?code='.$row->code);
$foo_code = explode(",",$foo_data);
$foo_id = $foo_code[9];
If I place the above lines before the MySQL Select statement then the $foo_data variable is empty as it hasnt been initialised yet.
How do I reference this variable in the MySQL statement eg:
SELECT `field1`, `field2`, COUNT(distinct $foo_id) AS Ref
I've tried:
SELECT `field1`, `field2`, COUNT(distinct {$foo_id}) AS Ref
SELECT `field1`, `field2`, COUNT(distinct '{$foo_id}') AS Ref
Anyone know if it's possable to reference a table row from the array obtained in the above file_get_contents() ?
Complete code as follows:
<?php
include $_SERVER['DOCUMENT_ROOT']. '/class2.php';
Global $currentUser;
$user_name = $currentUser['user_loginname'];
$user_call = strtoupper($user_name);
$user_region = $currentUser['user_region'];
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
</head>
<body>
<?
include("db_uploadlog.php");
if (!file_exists("db_uploadlog.php")) {
echo "Error - Config file is missing!";
}
else
{
$db_2 = mysql_connect($database_host, $database_username, $database_password);
mysql_select_db("db_name") or die("Cannot select database");
$foo_data = file_get_contents('http://foo.com/data_csv.php?code='.$row->code);
$foo_code = explode("|",$foo_data);
$foo_id - $foo_code[9]
$result = mysql_query("SELECT `column1`, `column1_id`, `code`, `column1_region`, '{$foo_id}' AS score FROM $table GROUP BY `column1` ORDER BY score DESC", $db_2);
$rowpos = mysql_num_rows($result);
$mnum = 1;
$mnum2 = 1;
if(mysql_num_rows($result) > 0)
{
?>
<table width="100%" align="center" border="0" cellpadding="0" cellspacing="0">
<tr>
<td width="2%"><b>Pos</b></td>
<td><b>Code</b></td>
<td width="10%"><b>Score</b></td>
</tr>
<?
for($i = 0; $i < mysql_num_rows($result); $i++)
{
$row = mysql_fetch_object($result);
?>
<tr>
<td><? echo $mnum2; ?></td>
<td><? echo $row->column1; ?></td>
<td><? echo $row->score; ?></td>
</tr>
<?
$mnum2 = $mnum2 + 1;
$mnum = $mnum + 1;
}
mysql_free_result($result);
mysql_close($db_2);
?>
</table>
</div>
<?
}
}
?>
</body>
</html>
Edited according to comment:
Then your problem is that file_get_contents don't recover data, you have to activate the property allow_url_fopen, set this property to 1 on your php.ini and your code should work
But i recommend you to use curl instead of file_get_contents you will have more control and curl was designed for this isn't it?
"If I place the above lines before the MySQL Select statement then the $foo_data variable is empty as it hasnt been initialised yet. "
This is probably because you reference the results from the MySQL select in your file_get_contents.
Other than that it should work, you are basically making a string in PHP and sending it to the MySQL server for parsing. So to MySQL it wont matter if you type it in by hand or if you use some pregenerated value.
Though, you need to trust the source if you are assembling the string from external sources, otherwise you should use PDO with bindParam.
edit
I see my initial thought was correct,
$foo_data = file_get_contents('http://foo.com/data_csv.php?code='.$row->code);
Here $row->code hasn't been initialized yet so file_get_contents goes to "http://foo.com/data_csv.php?code=" (if it goes anywhere at all).
You need to have another select above $foo_data which sets $row->code.
PHP normally shows an error message, but you probably are running on production mode. If you are testing you can put this in the top of your document
<?php
error_reporting(E_ALL);
ini_set("display_errors", 1);
?>
Which should help you debug your script a bit better.
I want to be able to sum up all the revenue that is being displayed in the page and it auto sums every time I added another data to the revenue column:
Following is my code :
<?php
require_once('Connections/connect.php');
$id_customer = mysql_real_escape_string($_GET['id_customer']);
$sql_PK = "SELECT * FROM tbl_delivery_details WHERE tbl_customer_id_customer = {$id_customer}";
$PK = mysql_query($sql_PK, $connect);
if ( mysql_error() ) {
die ( mysql_error());
}
$row_PK = mysql_fetch_assoc($PK);
$customer_name = $row_PK['tbl_customer_id_customer'];
$customer_name = mysql_real_escape_string($customer_name);
$sql = "SELECT tbl_customer.customer_name,
tbl_delivery_details.delivery_details_route,
tbl_delivery_details.delivery_details_destination,
tbl_delivery_details.delivery_details_van_no,
tbl_delivery_details.delivery_details_waybill_no,
tbl_delivery_details.delivery_details_charge_invoice,
tbl_delivery_details.delivery_details_revenue,
tbl_delivery_details.delivery_details_strip_stuff,
tbl_delivery_details.delivery_details_date
FROM tbl_customer, tbl_delivery_details
WHERE tbl_customer.id_customer = tbl_delivery_details.tbl_customer_id_customer
AND tbl_customer.id_customer = '{$customer_name}'";
$res = mysql_query($sql) or die(mysql_error());
$row = mysql_fetch_array($res);
$sum = 0;
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/x html">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Customer Revenue</title>
<link rel="stylesheet" type="text/css" href="qcc.css"/>
</head>
<body>
<table border="1">
<tr>
<th>Reveneu</th>
</tr>
<?php do { ?>
<tr>
<td><?php echo $row_PK['delivery_details_revenue'];?></td>
</tr>
<?php } while ($row_PK = mysql_fetch_assoc($PK));?>
<?php { ?>
<?php $sum+=$row_PK['delivery_details_revenue'] ?>
<?php } ?>
</table>
<?php echo $sum; ?>
</body>
</html>
When I load the page echo $sum always is zero how to correctly sum up the column I made that it will sum automatically if I add another data to it :
Instead of adding the revenue values up in PHP, why not have MySQL do it for you in the query?
$sql = "SELECT SUM(tbl_delivery_details.delivery_details_revenue) as revenue,
tbl_customer.customer_name,
tbl_delivery_details.delivery_details_route,
tbl_delivery_details.delivery_details_destination,
tbl_delivery_details.delivery_details_van_no,
tbl_delivery_details.delivery_details_waybill_no,
tbl_delivery_details.delivery_details_charge_invoice,
tbl_delivery_details.delivery_details_revenue,
tbl_delivery_details.delivery_details_strip_stuff,
tbl_delivery_details.delivery_details_date
FROM tbl_customer, tbl_delivery_details
WHERE tbl_customer.id_customer = tbl_delivery_details.tbl_customer_id_customer
AND tbl_customer.id_customer = '{$customer_name}'";
And then in youru view, just echo the SUM figure...
echo $row_PK['revenue'];
If I read this correctly, you're summing up the values outside of your while loop. That won't work.
I think you're mixing up a normal while loop, and a 'do while' loop.
See this code:
<?php do { ?>
<tr>
<td><?php echo $row_PK['delivery_details_revenue'];?></td>
</tr>
<?php } while ($row_PK = mysql_fetch_assoc($PK));?>
<?php { ?>
<?php $sum+=$row_PK['delivery_details_revenue'] ?>
<?php } ?>
It should be more along these lines:
<?php do { ?>
<tr>
<td><?php
echo $row_PK['delivery_details_revenue'];
$sum+=$row_PK['delivery_details_revenue']
?>
</td></tr>
<?php } while ($row_PK = mysql_fetch_assoc($PK));?>
this wouldn't happen if you would write the code a bit more clearly; try to avoid interleaving html and php so much:
<?php
do {
$revenue = $row_PK['delivery_details_revenue'];
$sum += revenue;
println("<tr><td>$revenue</td></tr>");
} while ($row_PK = mysql_fetch_assoc($PK));
?>
This is a lot clearer, if you ask me.
Well, I don't have a PHP interpreter in my head to run your code on sight. So, just a few things which I can spot
First, there is an SQL injection in your first query. Either cast your variable to integer
$id_customer = intval($_GET['id_customer']);
or treat it as a string in your query
$sql_PK = "SELECT * FROM tbl_delivery_details WHERE tbl_customer_id_customer = '$id_customer'";
or - better yet - use some database wrapper that allows you to use placeholders to represent actual data in the query.
Next, your query is incredible hard to read.
If your field names do not interfere, there is no reason to use table.field notation then.
Also use shortland aliases and consider using * if you want most of the fields from the table:
$sql = "SELECT SUM(delivery_details_revenue) as revenue,
customer_name, tbl_delivery_details.*
FROM tbl_customer, tbl_delivery_details
WHERE id_customer = tbl_customer_id_customer
AND id_customer = '$customer_name'";
By the way, while editing your query, I've noticed inconsistent naming: id_customer = '$customer_name'. Don't confuse yourself with wrong variable names. If it's id, then call it "id", not "name"
And also I see no point in the first query at all, if id_customer is equal to tbl_customer_id_customer. I think you need to simplify your code - it's compexity is the main reason why you're not getting your results, I believe.
Start from very simple query like
$sql = "SELECT SUM(delivery_details_revenue) as revenue,
FROM tbl_delivery_details
WHERE tbl_customer_id_customer = '$id_customer'";
and see if it returns anything.
If so - start adding some more data to fetch.
If no - check your data and overall data structure if it's all right.
im running this php script and not quite getting the result i want. at the moment its giving me this output
scuba tank
mike
0.00
450.00
5.00
2012-06-04 18:50:22
scuba tank
liam
80.00
350.00
2.50
2012-06-04 19:00:09
Displaying 3 results
scuba tank
josh
410.00
0.00
5.00
2012-06-04 19:00:09
its pretty much what i want except the line displaying 3 results should be displayed at the end instead of before the last entry. what do i need to do to my script to fix this?
<?php
$host = "localhost";
$user = "root";
$pass = null;
// ========================================
$dbhost = #mysql_connect($host, $user, $pass) or die("Unable to connect to server");
#mysql_select_db("divebay") or die("Unable to select database");
$var = "scuba";
$query = trim($var);
if(!isset($query)){
echo "Your search was invalid";
exit;
} //line 18
$sql = "SELECT * FROM auction WHERE name LIKE '%" . $query . "%'";
$result = mysql_query($sql);
$numrows = mysql_num_rows($result);
mysql_close($dbhost);
if($numrows == 0){
echo "Sorry, your search did not return any results";
}
$i = 0;
while($i < $numrows){
$row = mysql_fetch_array($result);
$ID = $row['ID'];
$name = $row['name'];
$owner = $row['owner'];
$holder = $row['holder'];
$start = $row['sprice'];
$current = $row['cprice'];
$instant = $row['iprice'];
$inc = $row['incprice'];
$image = $row['img'];
$time = $row['stime'];
$length = $row['duration'];
echo "
<?xml version = '1.0' encoding = 'utf-8'?>
<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org /TR/xhtml1/DTD/xhtml1-transitional.dtd'>
<html xmlns='http://www.w3.org/1999/xhtml'>
<head>
<title>searchdbresults</title>
</head>
<body>
<table style='width = 800px;'>
<tr style ='height = 200px;'>
<td style ='width = 200px;'></td>
<td style ='width = 300px;'>
<div style ='180px'> $name </div>
<div> $owner </div>
</td>
<td style='width =200px'>
<div style='height = 100px'> $current </div>
<div style='height = 50px'> $instant </div>
<div> $inc </div>
</td>
<td> $time </td>
</tr>
";
$i++;
}
echo "
<tr> Displaying $numrows results</tr>
</table>
</body>
</html>
";
?>
I can't comment, but there is several problems in your code.
1st the style must double quote
<div style="width:100%;">
for example.
2nd : there must be a td inside a tr for this line : Displaying $numrows results
and last one i see is : you have this :
<?xml version = '1.0' encoding = 'utf-8'?>
<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org /TR/xhtml1/DTD/xhtml1-transitional.dtd'>
<html xmlns='http://www.w3.org/1999/xhtml'>
<head>
<title>searchdbresults</title>
</head>
<body>
inside your while loop, so its several times in your page, and it must not
You also have the table opening in your while loop, but not the closing. So it's opened several times, but opened only once.
edit : you also need to add protection into your sql query
Your script is generating "messy" HTML. From what I see your so generated HTML page will have (in the current example) 3 DOCTYPE definitions, 3 head's as well as 3 opening table tags and only one closing /table. And also you don't need to echo every single html entity, you can use plain html in php files
Try something like that:
<?xml version = '1.0' encoding = 'utf-8'?>
<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'>
<html xmlns='http://www.w3.org/1999/xhtml'>
<head>
<title>searchdbresults</title>
</head>
<body>
<?php
$host = "localhost";
$user = "root";
$pass = null;
// ========================================
$dbhost = #mysql_connect($host, $user, $pass) or die("Unable to connect to server");
#mysql_select_db("divebay") or die("Unable to select database");
$var = "scuba";
$query = trim($var);
if(!isset($query)){
echo "Your search was invalid";
exit;
} //line 18
$sql = "SELECT * FROM auction WHERE name LIKE '%" . $query . "%'";
$result = mysql_query($sql);
$numrows = mysql_num_rows($result);
mysql_close($dbhost);
if($numrows == 0){
echo "Sorry, your search did not return any results";
}
else{
?>
<table style='width = 800px;'>
<?php
$i = 0;
while($i < $numrows){
$row = mysql_fetch_array($result);
$ID = $row['ID'];
$name = $row['name'];
$owner = $row['owner'];
$holder = $row['holder'];
$start = $row['sprice'];
$current = $row['cprice'];
$instant = $row['iprice'];
$inc = $row['incprice'];
$image = $row['img'];
$time = $row['stime'];
$length = $row['duration'];
?>
<tr style ="height: 200px;">
<td style ="width: 200px;"></td>
<td style ="width: 300px;">
<div style ="width: 180px"><?php echo $name; ?></div>
<div><?php echo $owner; ?></div>
</td>
<td style="width: 200px;">
<div style="height: 100px;"><?php echo $current; ?></div>
<div style="height: 50px;"><?php echo $instant; ?></div>
<div><?php echo $inc; ?></div>
</td>
<td><?php echo $time; ?></td>
</tr>
<?php
i++;
} //end of while
} //end of else
?>
<tr>
<td colspan="4">Displaying <?php echo $numrows; ?> results</td>
</tr>
</table>
</html>
And also consider preventing SQL Injection too: http://bobby-tables.com/
I think you would be much better off if you separated your php and html into separate files. You seem to be losing track of your opening " and closing ". If you want your
<tr> Displaying $numrows results</tr>
at the bottom of your page, then take it out of the table.
I'd suggest simplifying your table a little bit, maybe taking the 'Displaying $numrows results' out of the table entirely.
The line '<tr> Displaying $numrows results</tr>' is not valid HTML. <tr> means 'Define a new table row', but it needs a <td> inside it to wrap the content. Because most rows of your table contain several TD elements, whilst this row only contains one piece of information, you would need to tell that table cell to span multiple columns.
A good way of debugging this sort of thing is to feed the generated HTML to http://validator.w3.org/, or replace the $variables with sample data and feed the template code to a validator. This is usually a little frustrating at first (as it will force you to be exact about the HTML version you want to use, etc) but it is a good way of tracing problems. If you feed the following HTML snippet into the W3 validator, it will give you some useful feedback:
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head><title>A</title></head>
<body>
<table><tr><td>aaa</td><td>bbb</td></tr>
<tr><td>cccc</td><td>dddd</td></tr>
<tr>Test</tr>
</table>
</body>
</html>
The validator tells you that: Line 7, Column 5: character data is not allowed here
<tr>Test</tr>
In other words, the TR element should not directly contain text.
It also says that: Line 7, Column 13: end tag for "tr" which is not finished
<tr>Test</tr>
"Most likely, you nested tags and closed them in the wrong order... Another possibility is that you used an element which requires a child element that you did not include. Hence the parent element is "not finished", not complete. For instance, in HTML the <head> element must contain a <title> child element, lists require appropriate list items (<ul> and <ol> require <li> ...), and so on."
Once you have the static HTML looking, and validating, the way you want, you can then add the PHP loops back in, but this time you can compare the script output to your working HTML example.