Hi Gi, Please what wrong with my code. I have been trying it out for ours now.
<?php
include 'models/database.php';
$pdo = Database::connect();
$sql = 'SELECT * FROM customers ORDER BY staff_id DESC';
foreach ($pdo->query($sql) as $row) {
echo '<tr>';
echo '<td>'. $row['surname'] . '</td>';
echo '<td>'. $row['firstname'] . '</td>';
echo '<td>'. $row['sex'] . '</td>';
echo '<td>'. $row['dateofbirth'] . '</td>';
echo '<td>'. $row['qualification'] . '</td>';
echo '<td>'. $row['department'] . '</td>';
echo '<td>'. $row['yearjoined'] . '</td>';
echo '<td>'. $row['email'] . '</td>';
echo '<td width=250>';
echo '<a class="btn" href="read.php?id='.$row['staff_id'].'">Read</a>';
echo ' ';
echo '<a class="btn btn-success" href="update.php?id='.$row['staff_id'].'">Update</a>';
echo ' ';
echo '<a class="btn btn-danger" href="delete.php?id='.$row['staff_id'].'">Delete</a>';
echo '</td>';
echo '</tr>';
}
Database::disconnect();
?>
and I have a database like this
<?php
class Database
{
private static $dbName = 'terminal' ;
private static $dbHost = 'localhost' ;
private static $dbUsername = 'root';
private static $dbUserPassword = '';
private static $cont = null;
public function __construct() {
die('Init function is not allowed');
}
public static function connect()
{
// One connection through whole application
if ( null == self::$cont )
{
try
{
self::$cont = new PDO( "mysql:host=".self::$dbHost.";"."dbname=".self::$dbName, self::$dbUsername, self::$dbUserPassword);
}
catch(PDOException $e)
{
die($e->getMessage());
}
}
return self::$cont;
}
public static function disconnect()
{
self::$cont = null;
}
}
?>
it keeps showing Warning: Invalid argument supplied for foreach() in C:\xampp\htdocs\Payroll\viewstaffs.php on line 50 but when i change the name of the database to something esle like from terminal to payroll, the code works with out an error. Please can anyone help me check it out
Thanks alot . I was able to make it work after minutes of starring at it. All I did was remove "ORDER BY staff_id DESC" it worked after I removed that, but I really don't know why ?
Invalid argument supplied for foreach() is the typical error message when you provide a foreach loop with something other than an array, or Traversable instance/implementation. For example null or a boolean.
The docs help: PDO::query() returns a PDOStatement object, or FALSE on failure. (http://php.net/manual/pdo.query.php)
You should use PDO::errorInfo() to get some more hints (Docs: http://php.net/manual/pdo.errorinfo.php), for your code:
$pdo->errorInfo();
This sounds weird actually, since this should not be a question of data. Maybe it's a matter of permissions. I first thought maybe terminal is a reserved word, but couldn't find any evidence.
Otherwise, you might be better of if you set your PDO error mode to exception. Then you get an exception whenever something goes wrong. The default is silent (more info here http://php.net/manual/pdo.error-handling.php)
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
This is probably more handy in development, than in production.
On another note (unsolicited, so take it for what it's worth), you have a persistent (or stored) XSS security issue here. This is where XSS might be stored in the database (got there because of some other vulnerability allowing it to be entered in the first place) and subsequently written out to the browser with no sanitization. Best practice is to sanitize data coming in AND going out.
https://www.owasp.org/index.php/Cross-siteScripting(XSS))
If you add a simple piece of code, perhaps in a class with a static function, to sanitize your input, you could change:
echo '<td>'. $row['surname'] . '</td>';to something like:
echo '<td>'. Security::Sanitize($row['surname']) . '</td>';You'd have to write the function yourself, or find a decent library. It's a pain, I know, to do this every place you're sending data out, but in the end, it's well worth the effort.
Imagine if the surname field contained a bit of javascript from a malicious entry. For example, just a simple:
<script>alert('xss');</script>Without sanitizing, when sending the output to the browser, that javascript would actually be executed. Not good. Sanitizing this would possibly change this to just:
<script>alert('xss');</script>Harmless at that point.
Sanitizing could be as simple as a function like this, though a decent security library would be better. At least this is better than nothing.
class Security { public static function Sanitize($text) { $text = mb_detect_encoding($text, mb_detect_order(), true) === "UTF-8" ? $text : mb_convert_encoding($text, "UTF-8"); $html = htmlspecialchars($text, ENT_NOQUOTES | ENT_SUBSTITUTE, "UTF-8"); return $html; } }Anyway, thought I'd mention it, if it's of any value to you.