Mysql error message using PDO - mysql

I'd like my database not to insert duplicate e-mails, I used the unique key and it works perfectly. However, no message is shown to the user, and it seems like he signed up correctly, but when he tries to login he finds out it's impossible.
I made this code, but it returns success for both situations.
$sql4 = "INSERT INTO users (username, email, password, id_group, id_company)
VALUES (:username, :email, :password, :id_group, :id_company)";
$stmt4 = $PDO->prepare($sql4);
$stmt4->bindParam(':username', $username);
$stmt4->bindParam(':email', $email);
$stmt4->bindParam(':password',md5($password));
$stmt4->bindParam(':id_group', $id_group);
$stmt4->bindParam(':id_company', $id_company);
$stmt4->execute();
$erro = mysql_errno();
if ($erro == 0) {
echo '<p align="center">Success!</p>';
} elseif ($erro == 1062) {
echo '<p align="center"> Email already registered. Try using another.
</p>';
}

I tried another way and it worked:
$sql4 = $PDO->prepare("SELECT COUNT(*) as us FROM users WHERE email =
:email");
$sql4->bindValue(":email",$email);
$sql4->execute();
$row = $sql4->fetch();
if($row['us'] == '0'){
$sql4 = "INSERT INTO users (username, email, password, id_group, id_company)
VALUES (:username, :email, :password, :id_group, :id_company)";
$stmt4 = $PDO->prepare($sql4);
$stmt4->bindParam(':username', $username);
$stmt4->bindParam(':email', $email);
$stmt4->bindParam(':password',md5($password));
$stmt4->bindParam(':id_group', $id_group);
$stmt4->bindParam(':id_company', $id_company);
$stmt4->execute();
return '1';
//se o email for repetido exibe mensagem de erro.
}else{
echo 'Email already registered. Try another.';
}

Related

Symfony3 : How to do a massive import from a CSV file as fast as possible?

I have a .csv file with more than 690 000 rows.
I found a solution to import data that works very well but it's a little bit slow... (around 100 records every 3 seconds = 63 hours !!).
How can I improve my code to make it faster ?
I do the import via a console command.
Also, I would like to import only prescribers that aren't already in database (to save time). To complicate things, no field is really unique (except for id).
Two prescribers can have the same lastname, firstname, live in the same city and have the same RPPS and professional codes. But, it's the combination of these 6 fields which makes them unique !
That's why I check on every field before create a new one.
<?php
namespace AppBundle\Command;
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Helper\ProgressBar;
use AppBundle\Entity\Prescriber;
class PrescribersImportCommand extends ContainerAwareCommand
{
protected function configure()
{
$this
// the name of the command (the part after "bin/console")
->setName('import:prescribers')
->setDescription('Import prescribers from .csv file')
;
}
protected function execute(InputInterface $input, OutputInterface $output)
{
// Show when the script is launched
$now = new \DateTime();
$output->writeln('<comment>Start : ' . $now->format('d-m-Y G:i:s') . ' ---</comment>');
// Import CSV on DB via Doctrine ORM
$this->import($input, $output);
// Show when the script is over
$now = new \DateTime();
$output->writeln('<comment>End : ' . $now->format('d-m-Y G:i:s') . ' ---</comment>');
}
protected function import(InputInterface $input, OutputInterface $output)
{
$em = $this->getContainer()->get('doctrine')->getManager();
// Turning off doctrine default logs queries for saving memory
$em->getConnection()->getConfiguration()->setSQLLogger(null);
// Get php array of data from CSV
$data = $this->getData();
// Start progress
$size = count($data);
$progress = new ProgressBar($output, $size);
$progress->start();
// Processing on each row of data
$batchSize = 100; # frequency for persisting the data
$i = 1; # current index of records
foreach($data as $row) {
$p = $em->getRepository('AppBundle:Prescriber')->findOneBy(array(
'rpps' => $row['rpps'],
'lastname' => $row['nom'],
'firstname' => $row['prenom'],
'profCode' => $row['code_prof'],
'postalCode' => $row['code_postal'],
'city' => $row['ville'],
));
# If the prescriber doest not exist we create one
if(!is_object($p)){
$p = new Prescriber();
$p->setRpps($row['rpps']);
$p->setLastname($row['nom']);
$p->setFirstname($row['prenom']);
$p->setProfCode($row['code_prof']);
$p->setPostalCode($row['code_postal']);
$p->setCity($row['ville']);
$em->persist($p);
}
# flush each 100 prescribers persisted
if (($i % $batchSize) === 0) {
$em->flush();
$em->clear(); // Detaches all objects from Doctrine!
// Advancing for progress display on console
$progress->advance($batchSize);
$progress->display();
}
$i++;
}
// Flushing and clear data on queue
$em->flush();
$em->clear();
// Ending the progress bar process
$progress->finish();
}
protected function getData()
{
// Getting the CSV from filesystem
$fileName = 'web/docs/prescripteurs.csv';
// Using service for converting CSV to PHP Array
$converter = $this->getContainer()->get('app.csvtoarray_converter');
$data = $converter->convert($fileName);
return $data;
}
}
EDIT
According to #Jake N answer, here is the final code.
It's very very faster ! 10 minutes to import 653 727 / 693 230 rows (39 503 duplicate items!)
1) Add two columns in my table : created_at and updated_at
2) Add a single index of type UNIQUE on every column of my table (except id and dates) to prevent duplicate items with phpMyAdmin.
3) Add ON DUPLICATE KEY UPDATE in my query, to update just the updated_at column.
foreach($data as $row) {
$sql = "INSERT INTO prescripteurs (rpps, nom, prenom, code_prof, code_postal, ville)
VALUES(:rpps, :nom, :prenom, :codeprof, :cp, :ville)
ON DUPLICATE KEY UPDATE updated_at = NOW()";
$stmt = $em->getConnection()->prepare($sql);
$r = $stmt->execute(array(
'rpps' => $row['rpps'],
'nom' => $row['nom'],
'prenom' => $row['prenom'],
'codeprof' => $row['code_prof'],
'cp' => $row['code_postal'],
'ville' => $row['ville'],
));
if (!$r) {
$progress->clear();
$output->writeln('<comment>An error occured.</comment>');
$progress->display();
} elseif (($i % $batchSize) === 0) {
$progress->advance($batchSize);
$progress->display();
}
$i++;
}
// Ending the progress bar process
$progress->finish();
1. Don't use Doctrine
Try to not use Doctrine if you can, it eats memory and as you have found is slow. Try and use just raw SQL for the import with simple INSERT statements:
$sql = <<<SQL
INSERT INTO `category` (`label`, `code`, `is_hidden`) VALUES ('Hello', 'World', '1');
SQL;
$stmt = $this->getDoctrine()->getManager()->getConnection()->prepare($sql);
$stmt->execute();
Or you can prepare the statement with values:
$sql = <<<SQL
INSERT INTO `category` (`label`, `code`, `is_hidden`) VALUES (:label, :code, :hidden);
SQL;
$stmt = $this->getDoctrine()->getManager()->getConnection()->prepare($sql);
$stmt->execute(['label' => 'Hello', 'code' => 'World', 'hidden' => 1);
Untested code, but it should get you started as this is how I have done it before.
2. Index
Also, for your checks, have you got an index on all those fields? So that the lookup is as quick as possible.

save a link to mysql database php

I have a html form (for blogposts) and I want to save everything in a database table. It works fine but when I add a column for an image, which can also be uploaded in the same html form, then it is not saving anything.
Here's the code:
$imagepath = 'https://myurl.com/uploads/' . $_FILES['image']['name'];
$db = new PDO($dsn, $dbuser, $dbpass);
$query = $db->prepare(
"INSERT INTO posts (author, title, text, date, image)
VALUES(:author, :title, :text, NOW()), '$imagepath'");
$query->execute(array("author" => $author, "title" => $title, "text" => $text));
$db = null;
Try This..
<?php
if(isset($_POST['Upload'])) // upload button press
{
$file_name = $_FILES['file']['name'];
$file_size = $_FILES['file']['size'];
$file_type = $_FILES['file']['type'];
$file_temp = $_FILES['file']['tmp_name'];
$folder = "uploads/";
$file_url="http://localhost/../../uploads/$file_name"; //file location
move_uploaded_file($file_temp,"Song_uploads/".$file_name);
$sql="INSERT INTO imagepost(file_NAME,file_URL,file_SIZE) VALUES(:file_name,:file_url,:file_size)";
$stmt= $conn->prepare($sql);
$stmt->bindParam(':file_name',$file_name);
$stmt->bindParam(':file_url',$file_url);
$stmt->bindParam(':file_size',$file_size);
if($stmt->execute())
{
$message="<br/><h1> ---> "."[".$file_name."]"." File Has Been Uploaded !! </h1>";
}
else
{
$message="<br/> <h1> ---> "."[".$file_name."]"." File Not Be Uploaded !! Please Try Again !! </h1>";
}
}
?>
the closing parenthese is wrongly placed
"INSERT INTO posts (author, title, text, date, image)
VALUES(:author, :title, :text, NOW()), '$imagepath'");
should be
"INSERT INTO posts (author, title, text, date, image)
VALUES(:author, :title, :text, NOW(), '$imagepath' )");

Import XML File into mySQL with PDO

I need to import an XML file into an MySQL database.
I got an code already - but it's a few years old and don't use PDO and I did'nt get it working now on an new server with PHP7 and MySQL 5.5.
Would be very nice, if someone could help me with an working solution.
My XML file:
<amateures>
<amateur>
<id>
<login>
<figur>
<vote_rating>
<haarfarbe>
<gewicht>
<groesse>
<plz>
<sternzeichen>
<vorlieben>
<vorlieben_en>
<uebermich>
<uebermich_en>
<geschlecht>
<staat>
<gebtag>
<regdate>
<urls>
<profil>
<register>
</urls>
<images>
<overview>
<overview_fsk16>
<overview_big>
<overview_fsk16_big>
</images>
<videos>
<video>
<title>
<title_en>
<beschreibung>
<beschreibung_en>
<playtime>
<id>
<img_fsk16>
<img>
<imgani>
<videourl>
<category>
<category>
<category>
</video>
</videos>
</amateur>
<amateur>
[...]
</amateur>
</amateures>
I need the data in 3 tables:
Following data I need for table "amateure":
<amateur>
<id>
<login>
<figur>
<vote_rating>
<haarfarbe>
<gewicht>
<groesse>
<plz>
<sternzeichen>
<vorlieben>
<vorlieben_en>
<uebermich>
<uebermich_en>
<geschlecht>
<staat>
<gebtag>
<regdate>
<urls>
<profil>
<register>
</urls>
<images>
<overview>
<overview_fsk16>
<overview_big>
<overview_fsk16_big>
</images>
</amateur>
table "amateur_vid" should contain:
<videos>
<video>
<title>
<title_en>
<beschreibung>
<beschreibung_en>
<playtime>
<id>
<img_fsk16>
<img>
<imgani>
<videourl>
</video>
</videos>
and the table "amateur_cat" should contain:
<category>
The field "id" from section must be add to table "amateur_vid" and the filed "id" from section must be add to the table "amateur_cat".
This is my code - in this case only one category will be imported. I don't know how to do a loop over the nodes:
#!/usr/bin/php -n
<?php
function OpenDB () {
$connect = mysqli_connect('localhost','#','#');
if(!$connect)
die ("Connection to SQL-Server failed!");
$database = mysqli_select_db($connect, "DATABASE");
if(!$database)
die ("Selection of Database failed!");
return $connect;
}
$connect = OpenDB();
$count = 0;
$countnew = 0;
$countvid = 0;
$starttime = time();
$xml = simplexml_load_file("FILE.xml");
$query = "update amateur set deleted = 1";
mysqli_query($connect, $query);
$query = "delete from amateur_vid";
$res = mysqli_query($connect, $query);
foreach ($xml->amateur as $amateur) {
$count++;
$amateur_id = $amateur->id;
$amateur_login = utf8_decode($amateur->login);
$amateur_figur = $amateur->figur;
$amateur_vote_rating = $amateur->vote_rating;
$amateur_haarfarbe = $amateur->haarfarbe;
$amateur_gewicht = $amateur->gewicht;
$amateur_groesse = $amateur->groesse;
$amateur_plz = $amateur->plz;
$amateur_sternzeichen = $amateur->sternzeichen;
$amateur_vorlieben = $amateur->vorlieben;
$amateur_vorlieben_en = $amateur->vorlieben_en;
$amateur_uebermich = $amateur->uebermich;
$amateur_uebermich_en = $amateur->uebermich_en;
$amateur_geschlecht = $amateur->geschlecht;
$amateur_staat = $amateur->staat;
$amateur_gebtag = $amateur->gebtag;
$amateur_regdate = $amateur->regdate;
foreach ($amateur->urls as $url) {
$amateur_profil = $url->profil;
$amateur_register = $url->register;
}
foreach ($amateur->images as $image) {
$amateur_overview = $image->overview;
$amateur_overview_fsk16 = $image->overview_fsk16;
$amateur_overview_big = $image->overview_big;
$amateur_overview_fsk16_big = $image->overview_fsk16_big;
}
$amateur_vorlieben = mysqli_escape_string($connect, $amateur_vorlieben);
$amateur_vorlieben_en = mysqli_escape_string($connect, $amateur_vorlieben_en);
$amateur_uebermich = mysqli_escape_string($connect, $amateur_uebermich);
$amateur_uebermich_en = mysqli_escape_string($connect, $amateur_uebermich_en);
$query = "select * from amateur where amateur_id = $amateur_id";
$res = mysqli_query($connect, $query);
if(mysqli_num_rows($res) == 0) {
$countnew++;
$query = "insert into amateur (amateur_id, amateur_login, amateur_figur, amateur_vote_rating, amateur_haarfarbe, amateur_gewicht, amateur_groesse, amateur_plz, amateur_sternzeichen, amateur_vorlieben, amateur_vorlieben_en, amateur_uebermich, amateur_uebermich_en, amateur_geschlecht, amateur_staat, amateur_gebtag, amateur_regdate, amateur_profil, amateur_register, amateur_overview, amateur_overview_fsk16, amateur_overview_big, amateur_overview_fsk16_big) values ($amateur_id, '$amateur_login', '$amateur_figur', '$amateur_vote_rating', '$amateur_haarfarbe', '$amateur_gewicht', '$amateur_groesse', '$amateur_plz', '$amateur_sternzeichen', '$amateur_vorlieben', '$amateur_vorlieben_en', '$amateur_uebermich', '$amateur_uebermich_en', '$amateur_geschlecht', '$amateur_staat', '$amateur_gebtag', '$amateur_regdate', '$amateur_profil', '$amateur_register', '$amateur_overview', '$amateur_overview_fsk16', '$amateur_overview_big', '$amateur_overview_fsk16_big')";
$res = mysqli_query($connect, $query);
} else {
$query = "update amateur set amateur_login='$amateur_login', amateur_figur='$amateur_figur', amateur_vote_rating='$amateur_vote_rating', amateur_haarfarbe='$amateur_haarfarbe', amateur_gewicht='$amateur_gewicht', amateur_groesse='$amateur_groesse', amateur_plz='$amateur_plz', amateur_sternzeichen='$amateur_sternzeichen', amateur_vorlieben='$amateur_vorlieben', amateur_vorlieben_en='$amateur_vorlieben_en', amateur_uebermich='$amateur_uebermich', amateur_uebermich_en='$amateur_uebermich_en', amateur_geschlecht='$amateur_geschlecht', amateur_staat='$amateur_staat', amateur_gebtag='$amateur_gebtag', amateur_regdate='$amateur_regdate', amateur_profil='$amateur_profil', amateur_register='$amateur_register', amateur_overview='$amateur_overview', amateur_overview_fsk16='$amateur_overview_fsk16', amateur_overview_big='$amateur_overview_big', amateur_overview_fsk16_big='$amateur_overview_fsk16_big', deleted=0 where amateur_id = $amateur_id";
$res = mysqli_query($connect, $query);
if(!$res)
die($query);
}
foreach ($amateur->videos as $videos) {
foreach ($videos->video as $video) {
$vids_title = $video->title;
$vids_title_en = $video->title_en;
$vids_beschreibung = $video->beschreibung;
$vids_beschreibung_en = $video->beschreibung_en;
$vids_playtime = $video->playtime;
$vids_id = $video->id;
$vids_img_fsk16 = $video->img_fsk16;
$vids_img = $video->img;
$vids_imgani = $video->imgani;
$vids_videourl = $video->videourl;
$vids_category = $video->category;
$query = "insert into amateur_vid (amateur_id, vids_title, vids_title_en, vids_beschreibung, vids_beschreibung_en, vids_playtime, vids_id, vids_img_fsk16, vids_img, vids_imgani, vids_videourl, vids_category) values ($amateur_id, '$vids_title', '$vids_title_en', '$vids_beschreibung', '$vids_beschreibung_en', '$vids_playtime', '$vids_id', '$vids_img_fsk16', '$vids_img', '$vids_imgani', '$vids_videourl', '$vids_category')";
$res = mysqli_query($connect, $query);
$setid = mysqli_insert_id($connect);
$countvid++;
}
}
}
$query = "delete from amateur where deleted = 1";
mysqli_query($connect, $query);
?>
I would be really happy, if someone could help me with an working code snippet for my problem.
Thanks in advance.
Bee
I could change my old script and it's working now.
The only thing I did not get working is the <categories> section.
I need the categories in an seperate table - or, add the categories comma separated into one field.
Someone has an solution for this?

Ruby hash returning incorrect values

I have the following function in ruby for retrieving certain information from a database.
#Setup
require "mysql2"
#client = Mysql2::Client.new(:host => "127.0.0.1", :username => "root", :password => "password")
query = "use project1"
#client.query(query)
def nodeslastactive
query = "SELECT nodeid FROM nodes WHERE lastactive = #{#clock-1}"
result = #client.query(query)
if result.size == 0
return nil
else
resultarray = Array.new
result.each do |row|
resultarray.push(row["nodeid"])
end
end
end
It is utilized by this code:
lastactivenodes = nodeslastactive
if lastactivenodes != nil
lastactivenodes.each do |lastactivenode|
connect(node,lastactivenode)
end
end
The issue I am getting is that when the connection is established in the 2nd code block, the function tries to connect the node with the value {"nodeid"=>xxxxx}, even though I have copied all hash values out of the hash into an array in the 1st code block for processing by the second block. Any suggestions?
In the first method you miss the
return resultarray
in the else branch, or it will just return the result hash as it is the last thing evaluated in the method

Codeigniter database issue

Having a spot of bother trying to grab some data out of my database.
I have the following model:
function GetRestaurants($options = array())
{
// Qualification
if(isset($options['restaurantID']))
$this->db->where('restaurantID', $options['restaurantID']);
if(isset($options['restaurantRegionID']))
$this->db->where('restaurantRegionID', $options['restaurantRegionID']);
if(isset($options['restaurantName']))
$this->db->where('restaurantName', $options['restaurantName']);
if(isset($options['restaurantAddress1']))
$this->db->where('restaurantAddress1', $options['restaurantAddress1']);
if(isset($options['restaurantAddress2']))
$this->db->where('restaurantAddress2', $options['restaurantAddress2']);
if(isset($options['restaurantSuburb']))
$this->db->where('restaurantSuburb', $options['restaurantSuburb']);
if(isset($options['restaurantCity']))
$this->db->where('restaurantCity', $options['restaurantCity']);
if(isset($options['restaurantInformation']))
$this->db->where('restaurantInformation', $options['restaurantInformation']);
// limit / offset
if(isset($options['limit']) && isset($options['offset']))
$this->db->limit($options['limit'], $options['offset']);
else if(isset($options['limit']))
$this->db->limit($options['limit']);
// sort
if(isset($options['sortBy']) && isset($options['sortDirection']))
$this->db->order_by($options['sortBy'], $options['sortDirection']);
$query = $this->db->get("tblRestaurants");
if(isset($options['count'])) return $query->num_rows();
if(isset($options['restaurantID']))
return $query->row(0);
if(isset($options['limit']) && $options['limit'] == '1')
return $query->row(0);
return $query->result();
}
Now the following code works fine:
$this->load->model('Restaurants_model');
$data['restaurant'] = $this->Restaurants_model->GetRestaurants(array(
'restaurantName' => 'shed 5',
'limit' => '1'
));
However the following does not work:
$this->load->model('Restaurants_model');
$data['restaurant'] = $this->Restaurants_model->GetRestaurants(array(
'restaurantName' => str_replace('-', ' ', $this->uri->segment(2)),
'limit' => '1'
));
Even though the result of
str_replace('-', ' ', $this->uri->segment(2))
is in this instance: ‘shed 5’.
I have compared var_dumps of the output of the str_replace and the string itself and determined them to be identical. So why does the straight string return a result yet the string generated from the uri segment doesn’t? Some kind of encoding issue? My database holds data in ‘utf8_general_ci’.
Thanks for any suggestions!
$restaurant=str_replace('-', ' ', $this->uri->segment(2));
get value outside array and try array_push
$data['restaurant'] = $this->Restaurants_model->GetRestaurants(array(
'restaurantName' => $restaurant,
'limit' => '1'
));