send binary files from php to mysql using mysqli - php

i want to send data into two tables from a php script,the pic and idcard are two binary files that in mysql db and both of them have LONGBLOB type always the first insert query executed successfully(insert into user table) but the second query(insert into `applicant' table) have two situations:
1-if i make the pic and idcard field NULLABLE in db,other data except these two inserted successfully.
2-if i make the pic and idcard field NOT NULLABLE nothing insert into `applicant' table.
and both of two situation i cant save the binary data into my database,where is the problem?
and i also have no problem in $_FILES array and passing them,i can see the details of these fileds when i post it to the php script.
i think something is wrong with the send_long_data but i use it before exactly like now!
here is the script:
require_once('db_connection_config.php');
if (mysqli_connect_errno()) {
print_r("<div class='bs-example center-block'><div id='alertshow' class='bs-example center-block alert alert-danger'><a href='#' class='close' data-dismiss='alert'>×</a><strong>Connection Error:</strong>" . mysqli_connect_errno() . "</div></div>");
exit();
}
$today = date('Y:m:d');
$pass = randomPassword();
$stmt = $mysqli->prepare("INSERT INTO user (password,gender,firstname,lastname,email,phoneNum,mobileNum,Address,UserRoles_userRoleId) VALUES (?,?,?,?,?,?,?,?,3)");
$stmt->bind_param("sissssss", $pass, $_POST['gender'], $_POST['name'], $_POST['lastname'], $_POST['email'], $_POST['phonenum'], $_POST['mobilenum'], $_POST['address']);
$stmt->execute();
$mkey = mysqli_insert_id($mysqli);
$stmt->close();
if(isset($_FILES['pic']) && isset($_FILES['idcard'])){
$pic_file_path = $_FILES['pic']['tmp_name'];
if ( !file_exists($pic_file_path) ) {
throw new Exception('File not found.');
}
$pic_handle = fopen($pic_file_path, "rb");
if ( !$pic_handle ) {
throw new Exception('File open failed.');
}
$pic_content = null;
$idpic_file_path = $_FILES['idcard']['tmp_name'];
$idpic_handle = fopen($idpic_file_path, "rb");
$idpic_content = null;
$stmt = $mysqli->prepare("INSERT INTO applicant (userId,nationalCode,fatherName,birthPlace,nationality,religion,postalCode,picture,idpicture,registrationDate,militaryServiceStatus) VALUES (?,?,?,?,?,?,?,?,?,?,?)");
$stmt->bind_param("isssiisbbss", $mkey, $_POST['nationalcode'], $_POST['fathername'], $_POST['birthcity'], $_POST['nationality'], $_POST['religion'], $_POST['postalcode'], $pic_content, $idpic_content, $today, $_POST['mss']);
while (!feof($pic_handle)) {
$stmt->send_long_data(1, fread($pic_handle, 8192));
}
fclose($pic_handle);
while (!feof($idpic_handle)) {
$stmt->send_long_data(1, fread($idpic_handle, 8192));
}
fclose($idpic_handle);
$stmt->execute();
$stmt->close();
}
}
function randomPassword() {
$alphabet = "abcdefghijklmnopqrstuwxyzABCDEFGHIJKLMNOPQRSTUWXYZ0123456789";
$pass = array(); //remember to declare $pass as an array
$alphaLength = strlen($alphabet) - 1; //put the length -1 in cache
for ($i = 0; $i < 8; $i++) {
$n = rand(0, $alphaLength);
$pass[] = $alphabet[$n];
}
return implode($pass); //turn the array into a string
}

Related

foreign key does not update on cascade

I am using phpmyadmin 4.7.3 version. I made 2 tables with innoDB storage engine in a same database and i want to update foreign key automatically by using cascade but it does not work at all. In my dineOwnerUser table i have id field which is foreign key in webpromo table with the name of ownerid. Here are all step which i did to make it foreign key.
went to webpromo table
clicked on relation view button
after that i setup all option which is visible in image
So far i have explained which i have done the problem is that my webpromo table is totally empty even though foreign key is also not updating automatically. If i am wrong here kindly please guide me also I am posting my code just in case i am doing some thing wrong in coding here is my php code
<?php
session_start();
if(isset($_POST['recaptcha'])){
$secret = "************";
$response = $_POST['recaptcha'];
$remoteip = $_SERVER['REMOTE_ADDR'];
$url = file_get_contents("https://www.google.com/recaptcha/api/siteverify?secret=$secret&response=$response&remoteip=$remoteip");
$content = json_decode($url, TRUE);
if($content['success'] ==1){
function test_input($data) {
$data = trim($data);
$data = stripslashes($data);
$data = htmlspecialchars($data);
$data = strtolower($data);
return $data;
}
$discount = test_input($_POST["discount"]);
$discountitem = test_input($_POST["discountitem"]);
$website = test_input($_POST["website"]);
$expirydate = test_input($_POST["expirydate"]);
$desc = test_input($_POST["desc"]);
$filename;
if(isset($_FILES['logouploader']['name'])){
$filename = basename($_FILES['logouploader']['name']);
$filename = test_input($filename);
}
$dir = "img/uploads/";
$ext = strtolower(pathinfo($_FILES['logouploader']['name'], PATHINFO_EXTENSION));
$allowed = array('jpeg','png' ,'jpg');
if(!in_array($ext,$allowed) ) {
echo "wrongext";
$uploadOk = 0;
exit;
}
if ($_FILES["logouploader"]["size"] > 600000) {
echo "large";
$uploadOk = 0;
exit;
}
$uploadOk = 1;
if ($uploadOk == 0) {
echo "Sorry";
exit;
}
if ($uploadOk == 1) {
move_uploaded_file($_FILES["logouploader"]["tmp_name"], $dir.$filename);
$servername = "localhost";
$username = "*****";
$password = "*****";
try {
$conn = new PDO("mysql:host=$servername;dbname=*********", $username, $password);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$query = "INSERT INTO webpromo (discount, dealitem, website, expirydate, description, logouploader) VALUES (?, ?, ?, ?, ?, ?)";
$statement = $conn->prepare($query);
$statement->execute(
array(
$discount,
$discountitem,
$website,
$expirydate,
$desc,
$filename
) );
$conn = null;
exit;
echo "done";
}
catch(PDOException $e)
{
echo "Connection failed: " . $e->getMessage();
}
}
}
if($content['success'] !=1){
echo "notok";
$conn = null;
exit;
}
$conn = null;
exit;
}
?>
Note: i am getting image in my folder that's mean upto
move_uploaded_file($_FILES["logouploader"]["tmp_name"], $dir.$filename); my code is working fine
but after that when i try to populate my webpromo table with the form input values as well as uploaded image name it does not populate at all.
Thanks
You have got the wrong idea my friend it does not mean your data will be automatically inserted if you are using cascade.
What is used for actually is if the primary key value is updated then it updates the foreign key value in all respective tables.
You have to write a seperate insert query.

Update is too slow

Updating is way too slow:
//class for Database
class MyDB extends SQLite3
{
function __construct()
{
$this->open('/database.db');
}
}
//new db - Object
$db = new MyDB();
if(!$db){
echo $db->lastErrorMsg();
} else {
echo "Opened database successfully\n";
}
This code updates the database and gives me begin_time and length:
//BEGIN
$db->exec('BEGIN;');
//prepare update:
$smt2 = $db->prepare("UPDATE users SET username = :username, full_name = :full_name, is_private = :is_private, is_follower = 1, updated_on = :time, was_follower = NULL WHERE user_id = :usernameId");
//bind parameter
$smt2->bindParam(':usernameId', $usernameId);
$smt2->bindParam(':username', $username);
$smt2->bindParam(':full_name', $full_name);
$smt2->bindParam(':is_private', $is_private);
$smt2->bindParam(':time', $time);
//Prepare second update
$smt3 = $db->prepare("UPDATE users SET followed_on = IfNull(followed_on, :time) WHERE user_id = :usernameId");
//bind parameter
$smt3->bindParam(':usernameId', $usernameId);
$smt3->bindParam(':time', $time);
try {
echo "start\n";
$time_begin = time();
echo $time_begin;
//LOOP
foreach ($followers as $follower) {
$usernameId = $follower->getUsernameId();
$username = $follower->getUsername();
$full_name = $follower->getFullName();
$ProfilPicUrl = $follower->getProfilePicUrl();
$is_private = $follower->isPrivate();
//muss 0 sein, aber ist im mom einfach nur '' bei false.
if(strcmp($is_private, 1) !== 0){
$is_private = 0;
}
$time = time();
//Function, which returns rows, how often an entry exists in db (can only be 0 or 1)
$existence = item_exists($db, 'users', 'user_id', $usernameId);
if($existence)
{
//EXECUTE first update
$smt2->execute();
if(!$smt2){
echo $db->lastErrorMsg();
}
//EXECUTE second update
$smt3->execute();
if(!$smt3){
echo $db->lastErrorMsg();
}
}
}
//COMMIT
$db->exec('COMMIT;');
//TIME
$time_diff = time() - $time_begin;
echo "END: ". $time_diff . "\n";
}
catch (Exception $e) {
echo $e->getMessage();
}
I already use "BEGIN" and "COMMIT" and "prepare". But for an array with 10300 entries it still takes 173 seconds. Where I insert an array with 100.000 entries that took 8 seconds! What makes the update statement in this code so slow?
I merged the two update statements into one:
$smt2 = $db->prepare("EXPLAIN UPDATE users SET followed_on = IfNull(followed_on, :time), username = :username, full_name = :full_name, is_private = :is_private, is_follower = 1, updated_on = :time, was_follower = NULL WHERE user_id = :usernameId");
It still takes 87 seconds.
"EXPLAIN QUERY PLAN" :
0|0|0|SCAN TABLE users

Having trouble checking mysql database for existing user_id in PHP

I'm having a problem with the following PHP script. Specifically, the part that creates the user_id. This is part of a larger registration.php file that works fine without the section that creates the user_id.
As you can see, it's a while loop that uses a variable, $useridexits, to control the loop. It's set to true by default, so the loop runs. A random number is generated and then checked against the database. If a result is returned, the $useridexists variable is set to true and the loop continues. If no results are returned, $useridexists is set to false, so the loops stops. The number generated is then set to $userid and is then added to the database in the following section.
Here's the code:
//This section creates a new userid for each user.
//This varible is used by the while loop and is set to true by default.
$useridexists = true;
//While loop to create userid and check the database to see if the userid
//already exists. If it does, the while loop keeps going until a unique
//user id is created.
while($useridexists){
// Function to create random user id number.
function randomNumber($length) {
$result = '';
for($i = 0; $i < $length; $i++) {
$result .= mt_rand(0, 9);
}
return $result;
}
// user id value created from randomNumber function.
$number = randomNumber(1);
//query the database to see if the user id already exists
$query = "SELECT * FROM users WHERE user_id = :number";
$query_params = array(':number' => '$number');
try {
// These two statements run the query against the database table.
$stmt = $db->prepare($query);
$result = $stmt->execute($query_params);
}
catch (PDOException $ex) {
$response["success"] = 0;
$response["message"] = "Failed to run query: " . $ex->getMessage();
die(json_encode($response));
}
$row = $stmt->fetch();
if ($row){
$useridexists = true;
}else{
$useridexists = false;
}
}
$userid = $number;
// This section adds the values to the database:
$query = "INSERT INTO users (username, password, email, firstname, lastname, user_id) VALUES ( :user, :pass, :email, :firstname, :lastname, :uid)";
//update tokens with the actual data:
$query_params = array(
':user' => $_POST['username'],
':pass' => $_POST['password'],
':email' => $_POST['email'],
':firstname' => $_POST['firstName'],
':lastname' => $_POST['lastName'],
':uid' => $userid
);
//run the query, and create the user
try {
$stmt = $db->prepare($query);
$result = $stmt->execute($query_params);
}
catch (PDOException $ex) {
$response["success"] = 0;
$response["message"] = "Failed to run query: " . $ex->getMessage();
die(json_encode($response));
}
$response["success"] = 1;
$response["message"] = "Username Successfully Added! Please log in.";
echo json_encode($response);
$email= mysql_escape_string($_POST['email']);
$username = mysql_escape_string($_POST['username']);
If I comment out this section, everything works:
// user id value created from randomNumber function.
$number = randomNumber(1);
//query the database to see if the user id already exists
$query = "SELECT * FROM users WHERE user_id = :number";
$query_params = array(
':number' => '$number'
);
try {
// These two statements run the query against the database table.
$stmt = $db->prepare($query);
$result = $stmt->execute($query_params);
}
catch (PDOException $ex) {
$response["success"] = 0;
$response["message"] = "Failed to run query: " . $ex->getMessage();
die(json_encode($response));
}
$row = $stmt->fetch();
if ($row){
$useridexists = true;
}else{
$useridexists = false;
}
If I don't comment that section out, I don't get any errors, but nothing gets added to the database.
Everything works except the part that checks the database to see if the user_id already exists and changes the $useridexists variable to false, which should escape the while loop. When I add that, nothing gets added to the database.
BTW: I'm using a 1 digit value for testing purposes, but I'll change it to $number = randomNumber(7); once the code actually works.

SELECT_IDENTITY() not working in php

Scenario:
I have a SQL Query INSERT INTO dbo.Grades (Name, Capacity, SpringPressure) VALUES ('{PHP}',{PHP}, {PHP})
The data types are correct.
I need to now get the latest IDENTIY which is GradeID.
I have tried the following after consulting MSDN and StackOverflow:
SELECT SCOPE_IDENTITY() which works in SQL Management Studio but does not in my php code. (Which is at the bottom), I have also tried to add GO in between the two 'parts' - if I can call them that - but still to no avail.
The next thing I tried, SELECT ##IDENTITY Still to no avail.
Lastly, I tried PDO::lastInsertId() which did not seem to work.
What I need it for is mapping a temporary ID I assign to the object to a new permanent ID I get back from the database to refer to when I insert an object that is depended on that newly inserted object.
Expected Results:
Just to return the newly inserted row's IDENTITY.
Current Results:
It returns it but is NULL.
[Object]
0: Object
ID: null
This piece pasted above is the result from print json_encode($newID); as shown below.
Notes,
This piece of code is running in a file called save_grades.php which is called from a ajax call. The call is working, it is just not working as expected.
As always, I am always willing to learn, please feel free to give advice and or criticize my thinking. Thanks
Code:
for ($i=0; $i < sizeof($grades); $i++) {
$grade = $grades[$i];
$oldID = $grade->GradeID;
$query = "INSERT INTO dbo.Grades (Name, Capacity, SpringPressure) VALUES ('" . $grade->Name . "',". $grade->Capacity .", ".$grade->SpringPressure .")";
try {
$sqlObject->executeNonQuery($query);
$query = "SELECT SCOPE_IDENTITY() AS ID";
$newID = $sqlObject->executeQuery($query);
print json_encode($newID);
} catch(Exception $e) {
print json_encode($e);
}
$gradesDictionary[] = $oldID => $newID;
}
EDIT #1
Here is the code for my custom wrapper. (Working with getting the lastInsertId())
class MSSQLConnection
{
private $connection;
private $statement;
public function __construct(){
$connection = null;
$statement =null;
}
public function createConnection() {
$serverName = "localhost\MSSQL2014";
$database = "{Fill In}";
$userName = "{Fill In}";
$passWord = "{Fill In}";
try {
$this->connection = new PDO( "sqlsrv:server=$serverName;Database=$database", $userName, $passWord);
$this->connection->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
}
catch( PDOException $e ) {
die("Connection Failed, please contact system administrator.");
}
if ($this->connection == null) {
die("Connection Failed, please contact system administrator.");
}
}
public function executeQuery($queryString) {
$results = array();
$this->statement = $this->connection->query( $queryString );
while ( $row = $this->statement->fetch( PDO::FETCH_ASSOC ) ){
array_push($results, $row);
}
return $results;
}
public function executeNonQuery($queryString) {
$numRows = $this->connection->exec($queryString);
}
public function getLastInsertedID() {
return $this->connection->lastInsertId();
}
public function closeConnection() {
$this->connection = null;
$this->statement = null;
}
}
This is PDO right ? better drop these custom function wrapper...
$json = array();
for ($i=0; $i < sizeof($grades); $i++) {
//Query DB
$grade = $grades[$i];
$query = "INSERT INTO dbo.Grades (Name, Capacity, SpringPressure)
VALUES (?, ?, ?)";
$stmt = $conn->prepare($query);
$success = $stmt->execute(array($grade->Name,
$grade->Capacity,
$grade->SpringPressure));
//Get Ids
$newId = $conn->lastInsertId();
$oldId = $grade->GradeID;
//build JSON
if($success){
$json[] = array('success'=> True,
'oldId'=>$oldId, 'newId'=>$newId);
}else{
$json[] = array('success'=> False,
'oldId'=>$oldId);
}
}
print json_encode($json);
Try the query in this form
"Select max(GradeID) from dbo.Grades"

create new if already exists PHP

I am creating a random user ID, but I would like to check if the ID already has been used (very unlikely but the chances are there), but somehow this doesn't work. When I look in the database, there is no random character string in the account_id field. Do I call the functions in a wrong way?
function genRandomString() {
$length = 40;
$characters = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
for ($p = 0; $p < $length; $p++) {
$string .= $characters[mt_rand(0, strlen($characters))];
}
return $string;
}
function createID() {
$cl_id = 'h_u_'.genRandomString();
}
createID();
$sql_query="SELECT * FROM accounts WHERE account_id = :cl_id";
$statement = $conn->prepare($sql_query);
$statement->bindParam(':cl_id', $cl_id, PDO::PARAM_STR);
if ($statement->execute() && $row = $statement->fetch())
{
createID();
}
$conn->exec("INSERT INTO accounts SET
account_id='$cl_id' ,
name='$_POST[name]' ,
email='$_POST[email]' ");
$cl_id is a local variable in createID() function , you need to return your value to your global code ...
function createID() {
return $cl_id = 'h_u_'.genRandomString();
}
you need to check $id in the main code
$id = createID();
$sql_query="SELECT * FROM accounts WHERE account_id = '".$cl_id."'";
$statement = $conn->prepare($sql_query);
1 . You missed to return $c_id in createID(). Change it to:
function createID() {
return 'h_u_'.genRandomString();
}
$cl_id = createID();
2 . You could use good old uniqid() instead of your custom genRandomString().
This would lead to something simpler like:
function createID() {
return 'h_u_'.uniqid();
}
$cl_id = createID();
3 . You'll have to change the if in the database related code to a loop (have a look at my example below)
4 . Your insert query uses unverified $_POST vars. This is highly prone to SQL Injections. If your Database library supports server side prepared statements you should use them and you can feel secure because data is being kept separate from the query syntax. If you are using PHP with MySQL this is the case.
If you are not using server side prepared statements you should escape any $_POST data used in the query by using mysql_real_escape_string() or something like this. In the following example I'm assuming that you are using PHP with MySQL and thatswhy I use a prepared statement.
Taking all this in account may result in a finished script like this:
$sql_query="SELECT * FROM accounts WHERE account_id = :cl_id";
$statement = $conn->prepare($sql_query);
$maxtries = 3; // how many tries to generate a unique id?
for($i = 0; $i < $maxtries; $i++) {
$cl_id = uniqid(); // create a 'unique' id
$statement->bindParam(':cl_id', $cl_id, PDO::PARAM_STR);
if (!$statement->execute()) {
die('db error');
}
$row = $statement->fetch();
if($row) {
continue;
}
break;
}
// if a unique id couldn't get generated even
// after maxtries, then pigs can fly too :)
if($i === $maxtries) {
die('maximum number of tries reached. pigs can fly!');
}
// You should use a prepared statement for the insert to prevent from
// SQL injections as you pass $_POST vars to the query. You should further
// consider to validate email address and the name!
$name = $_POST['name'];
$email = $_POST['email'];
$insert_query = '
INSERT INTO accounts SET
account_id = :account_id,
name = :name,
email = :email';
$insert_statement = $conn->prepare($insert_query);
$insert_statement->bindParam(':account_id', $cl_id, PDO::PARAM_STR);
$insert_statement->bindParam(':name', $name, PDO::PARAM_STR);
$insert_statement->bindParam(':account_id', $email, PDO::PARAM_STR);
if (!$insert_statement->execute()) {
die('db error');
}

Categories