I have an index.php which is like:
require_once("../resources/config.php");
require_once(LIBRARY_PATH . "/mysql.php");
...
if(checkIfMailExists($email)) {
$error = true;
$errormsg = "This e-mail is already in use!";
}
mysql.php is:
try {
$pdo = new PDO('mysql:host=' . $config['db']['db1']['host'] . ';dbname=' . $config['db']['db1']['dbname'], $config['db']['db1']['username'], $config['db']['db1']['password']);
}catch(PDOException $e){
echo "Cant connect to mysql DB!";
}
function checkIfMailExists($email) {
$query = "SELECT * FROM users WHERE email = '".$email."'";
$num = $pdo->query($query);
if($num->rowCount() > 0){
return true;
}else{
return false;
}
}
And it appears, that $pdo from function is undefined. Even if i remove try-catch.
The only way i fixed it - i sent $pdo as a parameter to function, but it seems to be wrong. Any suggestions guys?
Sending a PDO connection as a parameter is actually the only sane way to do this. It is indeed good to know that you could use the global keyword, but the optimal way to write code that is possible to maintain is explicitely stating dependencies, and type-hinting them
function mailExists (PDO $pdo, $email) {
$sql = 'SELECT * FROM users WHERE email = :email';
$stmt = $pdo->prepare($sql);
$stmt->bindValue(':email', $email, PDO::PARAM_STR);
$stmt->execute();
return $stmt->rowCount() > 0;
}
if (mailExists($pdo, $email) {}
Read more here about PDO and prepared statements. Notice how I took advantage of named parameters to ensure that no sql injection is possible from this code.
PHP allows you to create local variables within a function without needing to do anything to declare them. Just start using a variable, and it's assumed to be a local variable.
This means if you want to access a global variable inside a function, you must declare it explicitly:
function checkIfMailExists($email) {
global $pdo;
. . .
Related
I have a function which retrieves user information and stores it in variables like so within a class:
public function UserInformation() {
$query = "SELECT * FROM users WHERE username = '$this->user'";
try {
$stmt = $this->db->prepare($query);
$stmt->execute();
}
catch(PDOException $ex)
{
die("Failed to run query: " . $ex->getMessage());
}
$rows = $stmt->fetch();
$email = $rows['email'];
$username = $rows['username'];
}
How would I then display a single variable from that function? I've tried echo $retrieveInfo->UserInformation->username; with no success, how would I do this?
You have defined local variables, that to be lost as soon as function ends its execution.
The more correct way of doing what you want would be to return the data from the function like:
$rows = $stmt->fetch();
return $rows;
And call the method like
$rows = $yourObject->UserInformation();
Or, if the object represents a particular user you could store the data retrieved in an instance members like:
$this->email = $rows['email'];
and then access them
$yourObject->email
This would work as well while the former is what I would prefer (I don't know the whole task though)
I have a PHP function that I am converting from using the mysql extension to the mysqli extension.
Everything is going okay, until here. I previously used a mysql_result to get a single piece of data. There is no direct equivalent in mysqli, so I have tried the following but it still doesn't work.
function getdbvalue($table,$value,$idfield,$id) {
$qrytext = "SELECT $value FROM $table WHERE $idfield LIKE '$id'";
$valueqry = mysqli_query($dbh,$qrytext);
if (FALSE === $valueqry) die("Select failed: ".mysqli_error);
$result = mysqli_fetch_row($valueqry);
$returnvalue = $result[0];
return $returnvalue;
}
I have verified that the variables are passing to the function okay, and the function is actually getting triggered. If I return $id I see the ID numbers.
I don't get an error for the query.
SOLVED:
I needed to add the database connection variable as a global in the function:
Working code:
function getdbvalue($table,$value,$idfield,$id) {
global $dbh; // This was missing!
$qrytext = "SELECT $value FROM $table WHERE $idfield LIKE '$id'";
$valueqry = mysqli_query($dbh,$qrytext);
if (FALSE === $valueqry) die("Select failed: ".mysqli_error);
$result = mysqli_fetch_row($valueqry);
$returnvalue = $result[0];
return $returnvalue;
}
Thanks to everyone for their help. :)
Although it's good idea to automate simple selects, the implementation is highly insecure, and should never be used.
Make it accept SQL query and parameters. It will make it secure.
And also you have to use PDO instead of mysqli
function getdbvalue() {
global $pdo;
$args = func_get_args();
$sql = array_shift($args);
$stm = $pdo->prepare($sql);
$stm->execute($args);
return $stm->fetchColumn();
}
have to be used like this (you have to connect to PDO first):
$name = getdbvalue("SELECT name FROM users WHERE id=?", $is);
this is the only proper way
I'm creating an authentification file with php and mysql, but I have this mistake in this line:
$stmt2->bind_param('ss',$twitter_id, $name);
The error message is
Call to a member function bind_param() on a non-object in ...
Where's my mistake?
$name in my database is a VARCHAR
$twitter_id in my database is a VARCHAR
$bd is my database connection
If a user is already registered, it should show me a message saying "User already registered", and if the user isn't registered, it should insert a new id and name in my database.
session_start();
if (!isset($_SESSION['userdata'])) {
header("location: index.php");
} else {
$userdata = $_SESSION['userdata'];
$name = $userdata->name;
$twitter_id = $userdata->id;
$stmt = $bd->prepare("SELECT ID_TWITTER FROM USERS");
$stmt->execute();
$stmt->bind_result($checkUser);
if ($stmt->fetch()) {
if($checkUser!==$twitter_id){
$cSQL = "INSERT INTO USERS (ID_TWITTER, FULL_NAME) VALUES(?,?)";
$stmt2 = $bd->prepare($cSQL);
$stmt2->bind_param('ss',$twitter_id, $name);
$stmt2->execute();
$stmt2->close();
} else {
echo "User already exits";
}
}
$stmt->close();
}
Could it be a typo? does $bd exist or should it be $db ?
Shameless plug: I do this exact thing in a project I have on github. Feel free to use the classes for whatever you like; they are mostly copy-pastable.
Your real issue is that $bd->prepare() returned false.
Check that you actually called it correctly and set it to new mysqli(*params)
The error Call to a member function ... on a non-object in ... means that $db is not an object, which means that it was not instantiated to an object. Thus, $this->method() isn't possible. bind_param(string $format, mixed &*vars); uses pass-by-reference and if this fails, it throws an error.
Try it yourself by sticking this in there:
$stmt->bind_param("ss", "string", "string");
To get around this issue where it can fail, check if $db->prepare() returns true:
if ($query = $bd->prepare($sql)) {
//stuff
}
In addition, in the first query you do it is probably not a good idea to be adding the overhead of a prepare for a single query that only checks row count without user input.
Solved : it works now
$stmt = $bd->prepare("SELECT ID_PROVIDER FROM USERS WHERE ID_PROVIDER = ?");
$stmt->bind_param('s', $twitter_id);
$stmt->execute();
$stmt->bind_result($checkUser);
while ($stmt->fetch()) {
$result = $checkUser;
}
if (empty($result)) {
$cSQL = "INSERT INTO USERS (ID_TWITTER, FULL_NAME)
VALUES(?,?)";
$stmt2 = $bd->prepare($cSQL);
$stmt2->bind_param('ss', $twitter_id, $name);
$stmt2->execute();
$stmt2->close();
}else {
echo "User already exits";
}
New to PDO. Here is my function. We are connected to the database and everything is working but this function when called is killing off the rest of PHP to be executed. Obviously something is wrong with it.
$dbh = new PDO("mysql:host=$host;dbname=$database", $username, $password);
global $dbh;
/*** set the error reporting attribute ***/
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
function selectall($table){
$stmt = $dbh->prepare("SELECT * FROM :table");
$stmt->bindParam(':table', $table, PDO::PARAM_STR,20);
$stmt->execute();
$result = $stmt->fetchAll();
return $result;
}
Called on a page like this:
<?php $telephones = selectall('telephone'); foreach($telephones as $telephones) { echo $telephone['title'].', '; } ?>
/// EDIT - I have tried all of your methods and the function is still breaking when called on the page. Here is the entire code. Slightly modified for testing purposes.
try {
$dbh = new PDO("mysql:host=$host;dbname=$database", $username, $password);
/*** set the error reporting attribute ***/
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$sql = "SELECT * FROM system";
foreach ($dbh->query($sql) as $row)
{
$url = $row['url'];
$election = $row['election'];
$election_date = $row['election_date'];
$sitename = $row['sitename'];
}
//FUNCTION
function selectall($table){
global $dbh;
$sql = "SELECT * FROM telephone";
foreach ($dbh->query($sql) as $row){
print $row['title'] .' - '. $row['name'] . '<br />';
}
}
/** close database connections **/
$dbh = null;
}
catch(PDOException $e) {
echo $e->getMessage();
}
The code outside the function ie. the one reflecting the table system is working perfectly Yet the one inside the function when called as a function later is killing off everything after it is called and is not executing.
Your second line generates a fatal error, when you're trying to use an undefined variable ($dbh) as an object.
You need to import it from the global scope like this:
global $dbh;
or pass it as a parameter to the function.
After you fix this, your code still won't work, as you cannot use parameters for identifiers (table or column names, or even in limit and offset). Unfortunately you have to resort to string concatenation there.
I think the problem is: $telephones as $telephones
Try this:
$telephones = selectall('telephone'); foreach($telephones as $telephone) { echo $telephone['title'].', '; }
Trying to get a grasp of using PDO, and I'm using some pre-made functions to make things simpler for when I want to do a query. First one connects, second runs the query.
Unfortunately it won't let me INSERT rows using dbquery(). SELECT works fine, just can't seem to get anything else to work.
Here's the code:
function dbConnect()
{
global $dbh;
$dbInfo['database_target'] = "localhost";
$dbInfo['database_name'] = "mysqltester";
$dbInfo['username'] = "root";
$dbInfo['password'] = "password";
$dbConnString = "mysql:host=" . $dbInfo['database_target'] . "; dbname=" . $dbInfo['database_name'];
$dbh = new PDO($dbConnString, $dbInfo['username'], $dbInfo['password']);
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$error = $dbh->errorInfo();
if($error[0] != "")
{
print "<p>DATABASE CONNECTION ERROR:</p>";
print_r($error);
}
}
function dbQuery($queryString)
{
global $dbh;
$query = $dbh->query($queryString);
$i = 0;
foreach ($query as $query2)
{
$queryReturn[$i] = $query2;
$i++;
}
if($i > 1)
{
return $queryReturn;
}
else
{
return $queryReturn[0];
}
}
PDO::query Only works with queries that return a result set (e.g. SELECT)
For INSERT/UPDATE/DELETE see PDO::exec
If you are going to be inserting user provided data into your DBMS I strongly suggest using the prepared statement functionality of PDO to provide automatic escaping to prevent SQL injection.
e.g.
<?php
$stmt = $dbh->prepare("INSERT INTO tester1 (name, age) VALUES (?, ?)");
$stmt->execute(array('James',25));
See PDO::prepare and PDOStatement::execute