I've been stuck on this for two days now. I have set up my own blog and the posts are stored in a database. This page is for grabbing an old post based on it's ID. When I try to retrieve them, everything shows but the actual body.
This is the index in /posts/
<?php
include_once('grabPost.php');
$TEMPLATE_TITLE = "$POST_TITLE";
include_once("../inc/template.html");
?>
Then, this is the grabPost.php.
<?php
error_reporting(-1);
$ID = $_GET['id'];
include_once('connectionMod.php');
$DBConnection = new MySQLi($DB_HOST, $DB_USER, $DB_PASS, $DB_DTBS);
function ReturnError($error){
global $POST_TITLE;
global $POST_BODY;
global $TEMPLATE_CONTENT;
$POST_TITLE="Oops!";
$POST_BODY="<p>It looks like we had an error grabbing your post. The post may have been moved, deleted, or you may have an invalid link. If you <strong>know</strong> this shouldn't be happening, please contact a developer.<br><em>$error</em></p>";
$TEMPLATE_CONTENT = "<h1>$POST_TITLE</h1>\n<hr size='2'>\n$POST_BODY";
}
if($ID == null){
ReturnError("No post ID was provided.");
}
if($stmt = $DBConnection->prepare("SELECT `Title`, `Poster`, `Date`, `Body` FROM `posts` WHERE `ID`=?")){
if(!($stmt->bind_param('i', $ID))){
ReturnError($stmt->error);
}
else if(!($stmt->execute())){
ReturnError($stmt->error);
}
else if(!($stmt->bind_result($POST_TITLE, $POST_NAME, $POST_DATE, $POST_BODY))){
ReturnError($stmt->error);
}
else if(!($stmt->fetch())){
ReturnError($stmt->error);
}
else{
$TEMPLATE_CONTENT = "<h1>$POST_TITLE</h1>\n<small>Posted on $POST_DATE by $POST_NAME</small>\n<hr size='2'>\n$POST_BODY";
}
}
else{
ReturnError($DBConnection->error);
}
?>
Oddly though, you can see the most recent post without issue on the homepage. Any suggestions with what's wrong?
Also, ReturnError() never shows the error. What can I do about it?
Function
function return_error($error){
$post_error = "<h1>Oops!</h1>\n<hr size='2'><br />"
."<p>It looks like we had an error grabbing your post."
."The post may have been moved, deleted, or you may have an invalid link."
."If you <strong>know</strong> this shouldn't be happening, "
."please contact a developer.<br><em>".$error."</em></p>";
return $post_error;
}
Usage:
/* check connection */
if ($DBConnection->connect_errno) {
$error = return_error("Connect failed: %s\n", $DBConnection->connect_error);
echo $error;
die();
}
/* check prepare() */
$stmt = $DBConnection->prepare("SELECT ....FROM `posts` WHERE `ID`=?");
if(!$stmt){
$error = return_error("prepare failed()".$stmt->error);
echo $error;
die();
}
and so forth ... By the way if connection fail or any other fatal error occurs, then die() or exit() is the right thing to do..
Well, I found the fix. I needed to run $stmt->store_result() before $stmt->bind_result() since since the body was a LONGTEXT, I guess this is some issue with MySQL and PHP.
Related
My .php includes quote.php followed with the rest of the page.
When the connection fails, I see "Fatal error: Uncaught mysqli_sql_exception: ----- include_once('C:\xampp\htdocs...') ----
and the remainder of the page does not load.
What must I do to display an error message, THEN the rest of my page?
Your situation is a rare case when using a try catch is justified.
All you need to do it wrap the include in a try-catch:
try {
require 'quote.php';
} catch(\Throwable $e) {
error_log($e); // for the future inspection
echo "Problem loading this part of page";
}
That's all. The error message will be shown and the rest of the page will be loaded.
But of course this approach should only be used when the content from quote.php is optional. In the every other case there must be no local try-catch but a site-wide error handler.
php / msqli is throwing exceptions. You need to write exception handler code (try { } catch (mysqli_sql_exception $e) { } code in your program to handle errors.
As a quick and sleazy workaroud for the current state of your code you can put this line of code at the top of your page. give this line of code
mysqli_report(MYSQLI_REPORT_OFF):;
This will suppress php exceptions and warnings, and let you rely completely on mysqli_connect_errno() to catch your errors.
Using #O. Jones idea and some nasty GoTO's, this does the job. The warnings and error are still displayed. The rest of the page is able to load now.
<?php
mysqli_report(MYSQLI_REPORT_OFF);
$dbServer = "localhost";
$dbUsername = "root";
$dbPassword = "";
$dbName = "project_01";
$conn = mysqli_connect($dbServer, $dbUsername, $dbPassword, $dbName);
// Check connection
if (mysqli_connect_errno())
{
echo "Failed to connect to the MySQL Database: ";
goto end;
}
$sql = "SELECT * FROM tbl_quotes";
if ($result=mysqli_query($conn,$sql))
{
// Return the number of rows in result set
$rowcount=mysqli_num_rows($result);
$rand = random_int(1,$rowcount);
} else {
echo "No records were found";
goto end;
}
$sql = "SELECT quote, credit FROM tbl_quotes where ID = $rand";
if ($result = mysqli_query($conn, $sql)) {
// Fetch one and one row
while ($row = mysqli_fetch_row($result)) {
printf ("%s" . " - " . "(%s)\n", $row[0], $row[1]);
}
// Free result set
mysqli_free_result($result);
}
end:
?>
Thanks to all who looked.
I created an HTML form to update my posts. So I used header() function to redirect the page to Updated page so I can see the changes. But I wanna echo a message on the redirected page. I have tried this code but this works only on same page, not redirected page.
<?php
$query_2 = "UPDATE posts SET post_image = '$post_image' WHERE post_id = $post_id ";
$query_2 .= "AND LENGTH('$post_image') > 0 AND post_image <> '$post_image' ";
$editPostImg = mysqli_query($connection, $query_2);
if (!$editPostImg) {
die("Something went wrong.<br>" . mysqli_error($connection));
}
header("Location: posts.php?source=edit_posts&p_id=$post_id");
echo "<p class='alert alert-success'><strong>Post Updated!</strong> <a href='../post.php?p_id=$post_id' class='alert-link' target='blank'>View Post</a><a href='' class='close' data-dismiss='alert'>x</a></p>";
}
?>
After the following line of code:
header("Location: posts.php?source=edit_posts&p_id=$post_id");
the user will be redirected to the new page and won't see the code that is executed after the header directive. To display the message you have to submit the message as GET or POST parameter. Whereas the first option will be the easier one.
As #Dharman mentioned your code is wide open to SQL Injections and should use parameterized prepared statements. You could use PDO or MySQLi. I build a solution with PDO but up to you.
Thus, you could adjust your script as follows:
<?php
try{
//Create new PDO Object
$conn = new PDO("mysql:host=HOST;port=PORT;dbname=DBNAME", USERNAME, PASSWORD);
//Define query
$query = $this->conn->prepare("UPDATE posts SET post_image = :postimage WHERE
post_id = :postid AND LENGTH(post_image) > 0 AND post_image <> :postimage");
$query->bindValue("postimage", $post_image);
$query->bindValue("postid", $post_id);
$query->execute();
//Redirect user and add success message as GET parameter
header("Location: posts.php?source=edit_posts&p_id=$post_id&update=success");
//Make sure script is terminated
exit();
} catch(Exception $ex){
//Log error
error_log($ex->getMessage());
//Show user custom error message
echo "Something went wrong";
//Make sure script is terminated
exit();
}
?>
On the target page (posts.php) you could then insert a code snippet as follows:
<?php
if(isset($_GET['update']) && $_GET['update'] == "success"){
echo "<p class='alert alert-success'><strong>Post Updated!</strong> <a href='../post.php?p_id=$post_id' class='alert-link' target='blank'>View Post</a><a href='' class='close' data-dismiss='alert'>x</a></p>";
}
?>
I have written the following function in PHP that has a mysqli_query in it that runs without any errors or exceptions. However, the INSERT INTO statement or $insert variable doesn't seem to be working as expected and I can't figure it out. I realize that posting only a portion of the code might make it difficult to ascertain why it is not working, but I am really looking for confirmation that there are no errors in this function.
Do I need to utilize mysqli_real_escape_string for every url provided? I tried altering $website to $_website to account for this, but it returned nothing.
Just really trying to figure out if there's anything I'm doing wrong here that's prevent the SQL query to work. It returns no error which is making it hard to debug. Thanks in advance!
$jp = mysqli_connect("localhost", "myuser", "password", "mydatabase");
if (!$jp) {
echo "Error: Unable to connect to MySQL." . PHP_EOL;
echo "Debugging errno: " . mysqli_connect_errno() . PHP_EOL;
echo "Debugging error: " . mysqli_connect_error() . PHP_EOL;
exit;
}
function create_distributor( $new_user_id ) {
$errors = new WP_Error();
$error=false;
$errorMsg='';
$logo=true;
$name=addslashes(htmlentities($_REQUEST['name']));
$contact=addslashes(htmlentities($_REQUEST['contact_info']));
$user_info = get_userdata( $new_user_id );
$website = $_POST['website'];
if (stripos($website, "http://") !== 0) //doesn't start with http:// ? , then add it
$website = "http://" . $website;
// $_website = mysqli_real_escape_string($jp, $website); // THIS DOESNT RETURN ANYTHING
$subdir = $user_info->user_nicename; // use nicename because user_login is obfuscated as unverified
$distribpath = 'http://ghq.com/dhdq/'.$subdir;
$ga_code = 'UA-15331916-1'; //default GA code
$logo = 'http://ghq.com/wp-content/themes/CAG/img/ghlogo.jpg'; //default png logo
if(!isset($_REQUEST['name']) || $_REQUEST['name']=='')
{
$error=true;
$errors->add('Distributor Name is required', __('<strong>ERROR</strong>:Distrubutor\'s name was not provided.'));
}
if($error)
{
return($errorMsg);
}
$insert="INSERT INTO distributor (id, name, contact, logo, path, subdir, website, ga_code) VALUES ('".$new_user_id."','".$name."','".$contact."','".$logo."','".$distribpath."','".$subdir."','".$website."','".$ga_code."')";
// var_dump($insert);
// The var_dump print out above is the following SQL Command which if copied and pasted
in phpmyadmin works fine: string(252) "INSERT INTO distributor (id, name, contact,
logo, path, subdir, website, ga_code) VALUES ('1748','test24','','http://ghq.com/wp-content/themes/CAG/img/ghlogo.jpg',
'http://ghq.com/dhdq/test24','test24','','UA-15331916-1')"
mysqli_query($jp, $insert);
if ( false===$insert ) {
printf("error: %s\n", mysqli_error($jp));
}
else {
echo 'done.';
}
if($error)
{
return $errors;
}
else
{
return($id);
}
}
The problem I can see straight off is you are checking your sql variable instead of the query result.
mysqli_query($jp, $insert);
if ( false===$insert ) {
printf("error: %s\n", mysqli_error($jp));
}
else {
echo 'done.';
}
Try changing it to:
$result = mysqli_query($jp, $insert);
if (!$result) {
printf("error: %s\n", mysqli_error($jp));
}else {
echo 'done.';
}
Also whats $jp? it doesn't look like you have assigned it anything. Make sure this is the variable that has your mysqli_connect on it. With your question regarding mysqli_real_escape_string, you should really be utilizing mysqli prepared statements as well. All user input should be sanitized.
Can someone point the fault in this code? I'm unable to update data to the database. We are sending a text message to the server, and this file here decodes and sets it in the database. But this case over here is not working for some reason. I checked and tried to troubleshoot, but couldn't find a problem.
case 23:
// Gather Variables
$Message = preg_replace("/\s+/","%20", $Message);
$UnixTime = time();
$cycle = explode(":", $Message);
$machine_press = $cycle[0];
$machine_pct_full = $machine_press/20;
$machine_cycles_return = $cycle[1];
$machine_cycles_total = $cycle[2];
// Build SQL Statement to update static values in the machine table
$sql = "UPDATE `machines` SET `machine_last_run`=".$UnixTime.",`machine_press`=".$machine_press.",`machine_pct_full`=".$machine_pct_full.",`machine_cycles_return`=".$machine_cycles_return.",`machine_cycles_total`=".$machine_cycles_total." WHERE `machine_serial`='$MachSerial'";
// Performs the $sql query on the server to update the values
if ($conn->query($sql) === TRUE) {
// echo 'Entry saved successfully<br>';
} else {
echo 'Error: '. $conn->error;
}
$sql = "INSERT INTO `cycles` (`cycle_sequence`,`cycle_timestamp`,`cycle_did`,`cycle_serial`,`cycle_03_INT`,`cycle_14_INT`,`cycle_15_INT`,`cycle_18_INT`)";
$sql = $sql . "VALUES ($SeqNum,$UnixTime,'$siteDID','$MachSerial',$machine_press,$machine_cycles_total,$machine_cycles_return,$machine_pct_full)";
// Performs the $sql query on the server to insert the values
if ($conn->query($sql) === TRUE) {
// echo 'Entry saved successfully<br>';
} else {
echo 'Error: '. $conn->error;
}
break;
More information is required to help you out with your issue.
First, to display errors, edit the index.php file in your Codeigniter
project, update where it says
define('ENVIRONMENT', 'production');
to
define('ENVIRONMENT', 'development');
Then you'll see exactly what the problem is. That way you can provide the information needed to help you.
I just saw that you are inserting strings when not wrapping them in apostrophe '. So you queries should be:
$sql = "UPDATE `machines` SET `machine_last_run`='".$UnixTime."',`machine_press`='".$machine_press."',`machine_pct_full`='".$machine_pct_full."',`machine_cycles_return`='".$machine_cycles_return."',`machine_cycles_total`='".$machine_cycles_total."' WHERE `machine_serial`='$MachSerial'";
and
$sql = "INSERT INTO `cycles` (`cycle_sequence`,`cycle_timestamp`,`cycle_did`,`cycle_serial`,`cycle_03_INT`,`cycle_14_INT`,`cycle_15_INT`,`cycle_18_INT`)";
$sql = $sql . " VALUES ('$SeqNum','$UnixTime','$siteDID','$MachSerial','$machine_press','$machine_cycles_total','$machine_cycles_return','$machine_pct_full')";
For any type of unknown problems I can recommend turning on PHP and SQL errors and use a tool called postman that i use to test my apis. You can mimic requests with any method, headers and parameters and send an "sms" just like your provider or whatever does to your API. You can then see the errors your application throws.
EDIT
I tested your script using a fixed version with ' and db.
$Message = "value1:value2:value3";
$MachSerial = "someSerial";
$SeqNum = "someSeqNo";
$siteDID = "someDID";
$pdo = new PDO('mysql:host=someHost;dbname=someDb', 'someUser', 'somePass');
// Gather Variables
$Message = preg_replace("/\s+/","%20", $Message);
$UnixTime = time();
$cycle = explode(":", $Message);
$machine_press = $cycle[0];
$machine_pct_full = (int)$machine_press/20; // <----- Note the casting to int. Else a warning is thrown.
$machine_cycles_return = $cycle[1];
$machine_cycles_total = $cycle[2];
// Build SQL Statement to update static values in the machine table
$sql = "UPDATE `machines` SET `machine_last_run`='$UnixTime',`machine_press`='$machine_press',`machine_pct_full`='$machine_pct_full',`machine_cycles_return`='$machine_cycles_return',`machine_cycles_total`='$machine_cycles_total' WHERE `machine_serial`='$MachSerial'";
try {
$pdo->query($sql);
} catch (PDOException $e) {
echo 'Query failed: ' . $e->getMessage();
}
$sql = "INSERT INTO `cycles` (`cycle_sequence`,`cycle_timestamp`,`cycle_did`,`cycle_serial`,`cycle_03_INT`,`cycle_14_INT`,`cycle_15_INT`,`cycle_18_INT`)";
$sql = $sql . "VALUES ('$SeqNum','$UnixTime','$siteDID','$MachSerial','$machine_press','$machine_cycles_total','$machine_cycles_return','$machine_pct_full')";
try {
$pdo->query($sql);
} catch (PDOException $e) {
echo 'Query failed: ' . $e->getMessage();
}
It totally works. Got every cycle inserted and machines updated. Before i fixed it by adding wrapping ' i got plenty of errors.
Alright so this is the solution:
i replaced the line:
$Message = preg_replace("/\s+/","%20", $Message);
with:
$Message = preg_replace("/\s+/","", $Message);
This removes all blank spaces in my text message and makes it a single string before breaking and assigning it to different tables in the database.
I understand this wasnt really a problem with the script and no one around would have known the actual problem before answering. and thats why i am posting the solution just to update the team involved here.
I have created a script for users to invite a friend using a email address, the email address and a randomly generated 10 character string 'inviteCode' is sent to a table called 'referrals'.
The invited person then receives an email with a URL link that contains their email and their unique inviteCode; http://website.com/register.php?email=email&inviteCode=1234567890
When the user clicks on the link the page register.php should then check the URL and if they data is valid in the 'referrals' table. If so then I have an include line to add the register form, if not then they are redirected. The point is nobody can access register.php unless they have been invited and sent a link.
At the moment the page keeps redirecting to index.php;
Register.php script:
<?php
include 'config.php';
if (isset($_GET['email'],$_GET['inviteCode'])) {
$mysqli = new Mysqli(/* your connection */);
$email = $mysqli->real_escape_string($_GET['email']);
$inviteCode = $mysqli->real_escape_string($_GET['inviteCode']);
$sql = "SELECT email,inviteCode FROM referrals WHERE email='".$email."' AND inviteCode='".$inviteCode."'";
$query = $mysqli->query($sql);
if ($query->num_rows > 0) { //check if values are correct and available in database
echo 'lol';
}
else
{
echo 'no';
exit;
}
}
else
{
echo 'problem'; //Page not accessible if neither email nor referral entered
}
?>
I replaced the first if statement with:
if(!isset($_GET['email']) || !isset($_GET['inviteCode'])) {
die(header('Location: index.php'));
} else
And I receive a blank page with no errors. I believe there may be something wrong with the email and invite code not being set.
Any help on this would be much appreciated (Y) thanks.
You should really be looking at handling the errors first. Try something like this:
if(!isset($_GET['email']) || !isset($_GET['inviteCode'])) {
die(header('Location: index.php'));
} else {
$mysqli = new Mysqli(/* your connection */);
$email = $mysqli->real_escape_string($_GET['email']);
$inviteCode = $mysqli->real_escape_string($_GET['inviteCode']);
$sql = "SELECT email,inviteCode FROM referrals WHERE email='$email' AND inviteCode='$inviteCode'";
$query = $mysqli->query($sql);
if ($query->num_rows > 0) { //check if values are correct and available in database
include'register-form.php';
} else {
die(header('Location: index.php'));
}
}
Breakdown
The if block checks to see if GET[email] or GET[inviteCode] are not set. if that is the case, kill the app with die() and redirect the user to index.php.
The second change is this line:
if ($query->num_rows > 0) {
That will check to ensure the rows returned are more than 0 (meaning there are actually rows returned.) Because you were just testing the presence of the $query->num_rows before.
Another Note:
Turn on error reporting, it will help you emensly during debugging:
ini_set('display_errors', 1);
error_reporting(E_ALL);
You could alternatively change your sql query to select the COUNT(id) and check if that is greater than 0, but that seems like overkill for what you're trying to do.
Do this to find out if anything is being returned by your query:
Start by making sure that the connection to your database is succeeding:
$mysqli = new Mysqli(/* your connection */);
if ($mysqli->connect_error) {
die('Connect Error (' . $mysqli->connect_errno . ') '
. $mysqli->connect_error);
}
$email = $mysqli->real_escape_string($_GET['email']);
Add that then let us know the results afterward, also provide specific error messages.
To debug your num_rows, replace this:
$query = $mysqli->query($sql);
if ($query->num_rows) //check if values are correct and available in database
{
include'register-form.php';
}
With this:
$query = $mysqli->query($sql);
$count = $query->num_rows;
print $count;
exit;
if ($query->num_rows) //check if values are correct and available in database
{
include'register-form.php';
}
If it shows 0, I have a suspicion it is because your sql statement needs to be concatenated.
"SELECT email,inviteCode FROM referrals WHERE email='".$email."' AND inviteCode='".$inviteCode."'";