I think we’re a little bit off topic now but thanks for helping.
I have stayed well clear of OOP for 7 years because I simply don’t understand it. However given that I want to learn C# in the coming few years I’m going to give it another try. I will write out some OOP PHP and PDO and come back once I have a noddy script.
Keep in mind that you don’t need to know how to write OOP to use it.
True, a basic understanding helps and knowing the syntax is essential, but there are a lot of OOP classes you can use now without needing to fuss much.
I suggest you turn on error reporting and display and give it a try (in your dev environment only please). The error messages will help you to learn what needs to be done.
Needs to be $dsn = 'mysql:dbname=dev;host=127.0.0.1';
Don’t replace dbname because that is how you connect to your database. It’s equivalent to procedural mysqli_*'s prepare($db, ..) where $db is the database you want to use.
Also, you should take note that square bracket arrays [] are available only from PHP 5.4 +. So don’t use square bracket arrays [] if you have PHP 5.3. You’ll get an error. Use array(); as an alternative if you have PHP 5.3 and below.
The reason why they are passing the $pdo/db variable is because in PHP, you don’t really want to create a new database connection every time you do a query. It’s easier to re-use the connection then closing it and re-opening it. In a way, it’s kind of like how system admins are with up-time.
You don’t need to. You can still use OOP mysqli_*.
<?php
// Connect to MySQL
$host = '127.0.0.1';
$username = 'dev';
$password = 'dev.dev';
$db = 'dev';
$mysqli = new mysqli($host, $username, $password, $db);
if($mysqli->connect_errno) {
die('Do not display any errors here. You should NEVER display errors to the user.');
}
$sql = 'SELECT 1 FROM flags WHERE flagname = ? AND ? BETWEEN MIN(flagvalue) AND MAX(flagvalue) LIMIT 1';
$prepare = $mysqli->prepare($sql);
$prepare->bind_param('ss', $flagname, $flagname2);
$prepare->execute();
$prepare->store_result();
if($prepare->num_rows) {
$prepare->bind_result($first_flag);
while($prepare->fetch()) {
print($first_flag);
}
} else {
print('No record with that information');
}
Also take note, you should always be using num_rows and rowCount() as it helps prevent white pages (nothing is displayed, no errors, no warning, nothing) and prevents error warning. It is also helps better user experience.
<?php
// Connect to MySQL
$dsn = 'mysql:dbname=dev_pof;host=127.0.0.1';
$username = 'dev';
$password = 'dev.dev';
$pdo = new PDO($dsn, $username, $password,[PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]);
// Function to validate the flag value
function CheckFlagValue($pdo, $FlagName, $FlagValue)
{
$sql = "SELECT 1 FROM flags WHERE flagname = ? AND flagvalue = ? LIMIT 1";
$stmt = $pdo->prepare($sql);
$stmt->execute([$FlagName, $FlagValue]);
return $stmt->fetchColumn();
}
// Function to get the flag description
function GetFlagDescription($pdo, $FlagName, $FlagValue)
{
$sql = "SELECT flagdescription FROM flags WHERE flagname = ? AND flagvalue = ? LIMIT 1";
$stmt = $pdo->prepare($sql);
$stmt->execute([$FlagName, $FlagValue]);
return $stmt->fetchColumn();
}
echo GetFlagDescription($pdo, 'intent', 9);
?>
The GetFlagDescription function is working and shows the flag description when the flag name and value are passed.
However CheckFlagValue I need this function to return true or false depending on the row count. There doesn’t seem to be a row count function for PDO??
rowCount needs to be rowCount();
It has to be after the ->execute() or it won’t work. Also, it’s best to check if the row actually exists for all your query calls. Let’s say you only have 2 rows of data in your database and someone typed in their address bar ?flag=3. What then? It’ll display a big white blank page and nothing else. If you don’t handle errors the right way, your users will question, “Does this webmaster know what he’s doing because the page shows nothing?”
It’s best to handle errors the proper way so that users don’t keep sending feedbacks about blank pages. This is also a way for hackers to hack your website. If your page crashes after a certain amount of data, they know that those data don’t exist and they can exploit it. So rather than giving them a free pass, you should handle your errors the right and proper way by using num_rows (mysqli_*) and rowCount() (PDO).
// Function to validate the flag value
function CheckFlagValue($pdo, $FlagName, $FlagValue)
{
$sql = "SELECT 1 FROM flags WHERE flagname = ? AND flagvalue = ? LIMIT 1";
$stmt = $pdo->prepare($sql);
$stmt->execute([$FlagName, $FlagValue]);
if ($stmt->rowCount() == 1) {
return true;
} else {
return false;
}
}
== 1, > 0, < 1, and many other ones aren’t necessary. Normally you would find those conditions on a tutorial for noobies. With num_rows and rowCount, if the data exists, it’ll return a 1 which means true. If the data doesn’t exist, it’ll return a 0 which means false. In any case it would be like if(true == true) when you already know it’s already true and will always return the first error checking. False would always be returned in the else statement. That’s being really redundant so it’s not really necessary to repeat one’s self by comparing the condition when the data is returned as true already.
So this is fine if you were to use it in an if statement.
Yup and the best part is, if num_rows or rowCount() returns a 1. It’ll automatically return what is in the if statement no matter what. And like I said above, if num_rows or rowCount() returns a 0, it’ll return what is in the else statement.
So it’s not really needed to do something like
if($stmt->rowCount() == 0) when it’s exactly the same as } else {. And same with if($stmt->rowCount() == 1) when it’s exactly the same thing as if($stmt->rowCount())
Look, you’ve gone astray from the plain and simple working code I gave you already. You don’t need a count actually. To count something is to make yourself aware of how many something you have.
In your case you don’t need it. You need only know whether you have somethng or not. It’s different question. For this you need just select something and see whether anything was returned. As simple as that. Exactly what my code does.
While you should never use rowCount or num_rows to see whether your query returned something or not. Because you already have the selected data iself - no need anything else.
return $stmt->fetchColumn();
See, here you selected one row from the database and fetched it. That’s exactly what you should do when working with database. If it returns a value (1), then it will be returned from function which will be count as TRUE. If no row found, then this code will return FALSE. Exactly what you need. That’s why this function works as intended. No extra code needed, No row count or comparisons required.
While your approach with rowCount is wrong. It makes no sense to select some data but not to fetch it.
you should handle your errors the right and proper way by using num_rows (mysqli_*) and rowCount()
Don’t listen to that guy. He just have no idea what he’s talking about. This function has absolutely nothing to do with whatever error handling at all
The difference being that thsoe return 0 or 1 where comparing it to 1 returns true or false as it would then be the result of the comparison that is returned rather than the value - just as in the original
if(condition) return true else return false
and return condition
are equivalent in that both return true or false and not the value of part of the condition
<?php
class ScriptControl
{
private $pdo;
private $ScriptName;
public function __construct($pdo, $ScriptName)
{
$this->pdo = $pdo;
$this->ScriptName = $ScriptName;
}
public function IsEnabled();
{
$sql = "SELECT 1 FROM config WHERE config_name = ? AND config_value = 1 LIMIT 1";
$stmt = $this->pdo->prepare($sql);
$stmt->execute([$this->ScriptName]);
return $stmt->fetchColumn();
}
public function IsRunnable();
{
date_default_timezone_set("Europe/London");
$time = date("Hi");
$sql = "SELECT 1 FROM config WHERE config_name = ? AND config_value = ? LIMIT 1";
$stmt = $this->pdo->prepare($sql);
$stmt->execute([$this->ScriptName, $this->$time]);
return $stmt->fetchColumn();
}
}
?>
and…
<?php
include_once('PDO.class.php');
include_once('ScriptControl.class.php');
$ThisScript = new ScriptControl('SendMessage');
if ( (!$ThisScript->isEnabled()) && (!isset($_POST['bypass'])) )
{
echo "<p>This script is not enabled</p>\n";
die();
}
if ( (!$ThisScript->isRunable()) && (!isset($_POST['bypass'])) )
{
echo "<p>This script is not scheduled to run</p>\n";
die();
}
?>
The IsEnabled will be used by about 10 different scripts, whereas the IsRunnable will only be used by 1 so is it right to put them together in the same class?