"Function name must be a string" on INSERT - mysqli PHP - php

I have puzzled over this for some time. It is puzzling because a very similar query just a few lines above works fine. I am very new to mysqli, so there may be something very fundamental I am missing.
The connection is set up like this:
Class dbObj{
/* Database connection start */
var $servername = "myserver";
var $username = "myusername";
var $password = "mypassword";
var $dbname = "mydb";
var $conn;
function getConnstring() {
$con = mysqli_connect($this->servername, $this->username, $this->password, $this->dbname) or die("Connection failed: " . mysqli_connect_error());
/* check connection */
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
} else {
$this->conn = $con;
}
return $this->conn;
}
}
Then, in an Ajax processing file:
include_once({the connection file above});
$db = new dbObj();
$connString = $db->getConnstring();
$params = $_REQUEST;
$action = isset($params['action']) != '' ? $params['action'] : '';
$NeedsCls = new Needs($connString);
Then, inside a class called "Needs":
protected $conn;
protected $data = array();
function __construct($connString)
{
$this->conn = $connString;
}
function insertNeeds($params)
{
$ExpDate = $params[Expire];
$sql = "INSERT INTO `pNeeds` (PubCode, Title, Description, Keywords, Expire) VALUES('".$_SESSION["PubCode"]."','".$params["Title"]."','".$params["Description"]."','".$params[NeedsTags]."','".$ExpDate."'); ";
echo $result = mysqli_query($this->conn, $sql) or die("Error - Failed inserting Needs data");
$Record = $db->insert_id;
$KW = explode(';',$params[NeedsTags]);
$KWCount = count($KW);
for($x=0;$x<$KWCount;$x++)
{
$Keyword = $KW[$x];
$sql = "INSERT INTO `Keywords` (Keyword, PubCode, Table, Record, Expire) VALUES ('".$Keyword."','".$_SESSION["PubCode"]."','pNeeds','".$Record."','".$ExpDate."'); ";
echo $result = mysqli_query($this->conn,$sql) or die("Error - Keywords not saved<br />".$mysqli_error());
}
}
The first query works fine. The second fails with the error "Function name must be a string". I've verified the data going into the Ajax code is correct. It doesn't appear that I am missing something stupid. (famous last words) The error message makes no sense to me. Similar posts here on StackOverflow and elsewhere do not seem to pertain in this instance.

It looks like you're just grabbing $params wrong:
$ExpDate = $params[Expire];
$params[NeedsTags];
Should be:
$ExpDate = $params['Expire'];
$params['NeedsTags'];
Edit
You're actual error is from:
$mysqli_error()
Remove the $
Edit
RationalRabbit: To avoid confusing anyone, I should mention that the whole syntax was wrong. Using object oriented mysqli, the error syntax should have been
db->error
OR
mysqli($this->conn)

Related

PHP/MYSQL Updating Multible Tables and Could not update data: Query was empty

I started to learn PHP, have made a great way for myself (not for PHP world) but I cannot succeed updating the information part.. I have problem about updating multiptle tables, and keep receiving this nice error: Could not update data: Query was empty.
I've searched a lot, have been fighting with that for a week and tried to do my best but no result. That's why I am posting here. By the way I know that my code is not neither whole PDO nor MYSQLI but I'm trying my best to learn and implement them as well..
I have got 3 tables now: Students - LessonsBought - Payments.
1) students_id is a joined one with students_id in other tables.
2) students_id is a foreign Key with lessonsbought_id and payments_id
(InnoDB)
Here is my code :
<?php
$servername = "localhost";
$username = "MY-DB-USERNAME";
$password = "MY-DB-PASSWORD";
$dbname = "MY-DB-NAME";
$conn = mysql_connect($servername, $username, $password, $dbname);
if(isset($_POST['update']))
{
$students_name = $row['students_name'];
$students_phone = $row['students_phone'];
$students_email = $row['students_email'];
$students_grade = $row['students_grade'];
$students_reg_date = $row['students_reg_date'];
$lessonsbought_type = $row['lessonsbought_type'];
$lessonsbought_hour = $row['lessonsbought_hour'];
$payment_total = $row['payment_total'];
$payment_method = $row['payment_method'];
$payment_done = $row['payment_done'];
$payment_waiting = $row['payment_waiting'];
$students_id = $_GET["id"];
$sql = mysql_query("UPDATE students,lessonsbought,payment SET
students_name = '$students_name', students_phone = '$students_phone',
students_email = '$students_email', students_grade = '$students_grade',
students_reg_date = '$students_reg_date',
lessonsbought_type= '$lessonsbought_type',
lessonsbought_hour='$lessonsbought_hour',payment_total='$payment_total',
payment_method = '$payment_method', payment_done='$payment_done',
payment_waiting = '$payment_waiting', WHERE students_id =
'$students_id'");
$retval = mysql_query( $sql, $conn );
if(!$retval )
{
die('Could not update data: ' . mysql_error());
}
echo "Updated data successfully\n <font color='green'>
<b>Record deleted successfully</b><font><br />
<a class='buttons' href='/result.php'>Turn Back To Result Page</a>";
}
?>
first you have to select database
mysql_select_db("database_name");
secondly use separate update query to update different table
thirdly you are calling mysql_query inside another mysql_query.
your sql variable will be just query. like shown below
$sql="UPDATE students SET students_name = '$students_name', students_phone = '$students_phone' WHERE students_id = '$students_id'";
lastly Please stop using mysql_* functions.
I have taken some of your code and added it into PDO so you can see how you should be doing this. In this instance it'll work also once all fields have been entered;
Firstly, set yourself up a database connection file:
class Database
{
private $host = "localhost";
private $db_name = "dbname";
private $username = "user";
private $password = "pass";
public $conn;
public function dbConnection()
{
$this->conn = null;
try
{
$this->conn = new PDO("mysql:host=" . $this->host . ";dbname=" . $this->db_name, $this->username, $this->password);
$this->conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch(PDOException $exception)
{
echo "Connection error: " . $exception->getMessage();
}
return $this->conn;
}
}
Then, I'd make a DBCommon file also. You need to ensure you require_once the database connect file:
class DBCommon
{
private $conn;
/** #var Common */
public $common;
public function __construct()
{
$database = new Database();
$db = $database->dbConnection();
$this->conn = $db;
}
public function runQuery($sql)
{
$stmt = $this->conn->prepare($sql);
return $stmt;
}
}
Then you need to make your classes, so for this one it'd be for example, class student;
class student extends DBCommon
{
public function __construct()
{
parent::__construct();
}
public function updateStudent($name, $phone, $email, $grade)
{
$userid = $_SESSION['user_session'];
$stmt = $this->runQuery("UPDATE `tablename` SET `students_name` = :sname, `students_phone` = :phone, `students_email` = :email, `students_grade` = :grade WHERE `students_id` = :sid");
$stmt->bindParam(array(':sname' => $name, ':phone' => $phone, ':email' => $email, ':grade' => $grade, ':sid' => $userid));
$stmt->execute();
echo "Your Records have now been updated.";
}
}
You can add a try / catch block around these to pass back an error message.
Then within your form file you'd need to include the classes file and then create the class and then form your trigger for the code to run when you press the submit button like below:
require_once ('class.file.php');
$class = new student();
if (isset($_POST['update']))
{
$class->updateStudent($_POST['name'], $_POST['phone'], $_POST['email'], $_POST['grade']);
}
I know this doesn't precisely tell you what you've done wrong but the major wrong thing you have done is gone via MySQL_. This way is a much cleaner and effective way.
P.S. Always bind your params never use '{$var}' within your queries as you'll be subject to vulnerabilities.

OOP PHP Database results to Array

I am new to the idea of oop php and i am trying to write an irc php.
What I'm trying to do:
I am trying to query my database, get results from my database and put it into an array inside my program.
I tried making a new function to carry out the task and called it in the __construct function.
I have shortened the code but it pretty much looks like this:
Any thoughts and ideas are much appreciated.
class IRCBot
{
public $array = array();
public $servername = "localhost";
public $username = "root";
public $password = "usbw";
public $dbname = "bot";
function __construct()
{
//create new instance of mysql connection
$conn = new mysqli($this->servername, $this->username, $this->password, $this->dbname);
if ($mysqli->connect_errno)
{
echo "Failed to connect to MySQL: (" . $mysqli->connect_errno . ") " . $mysqli->connect_error;
}
echo $mysqli->host_info . "\n";
$this->database_fetch();
}
function database_fetch()
{
$query = "SELECT word FROM timeoutwords";
$result = mysqli_query($query);
while($row = mysqli_fetch_assoc($result))
{
$array[] = $row();
}
}
function main()
{
print_r($array);
}
}
$bot = new IRCBot();
Changes
1) Change if ($mysqli->connect_errno) to if ($conn->connect_errno)
2) Change $array[] = $row(); to $array[] = $row;
3) Add return $array; in function database_fetch()
4) Call database_fetch() function inside main() function instead of constructor.
5) Add $this->conn in mysqli_query() (Thanks #devpro for pointing out.)
Updated Code
<?php
class IRCBot
{
public $array = array();
public $servername = "localhost";
public $username = "root";
public $password = "usbw";
public $dbname = "bot";
public $conn;
function __construct()
{
//create new instance of mysql connection
$this->conn = new mysqli($this->servername, $this->username, $this->password, $this->dbname);
if ($this->conn->connect_errno)
{
echo "Failed to connect to MySQL: (" . $this->conn->connect_errno . ") " . $this->conn->connect_error;
}
}
function database_fetch()
{
$query = "SELECT word FROM timeoutwords";
$result = mysqli_query($this->conn,$query);
while($row = mysqli_fetch_assoc($result)){
$array[] = $row;
}
return $array;
}
function main()
{
$data = $this->database_fetch();
print_r($data);
}
}
Quick Start
Object Oriented Programming in PHP
Classes and Objects
Principles Of Object Oriented Programming in PHP
First of all you need to fix error from your constructor, you can modify as:
function __construct()
{
//create new instance of mysql connection
$this->conn = new mysqli($this->servername, $this->username, $this->password, $this->dbname);
if ($this->conn->connect_errno)
{
echo "Failed to connect to MySQL: (" . $this->conn->connect_errno . ") " . $this->conn->connect_error;
}
echo $this->conn->host_info . "\n";
}
Here, you need to replace $mysqli with $conn because your link identifier is $conn not $mysqli
No need to call database_fetch() here.
You need to use $conn as a property.
Now you need to modify database_fetch() method as:
function database_fetch()
{
$query = "SELECT word FROM timeoutwords";
$result = mysqli_query($this->conn,$query);
$array = array();
while($row = mysqli_fetch_assoc($result))
{
$array[] = $row;
}
return $array;
}
Here, you need to pass add first param in mysqli_query() which should be link identifier / database connection.
Second, you need to use return for getting result from this function.
In last, you need to modify your main() method as:
function main()
{
$data = $this->database_fetch();
print_r($data);
}
Here, you need to call database_fetch() method here and than print the data where you need.

Php calling a function saving into database

How can I run the functions save and update? It seems there's no error on my code..but still is not functioning. I need to save and update with the shortest code..thanks!
<?php
$mysqli = new mysqli("localhost","root","","sample_db");
if ($mysqli->connect_errno) {
printf("Connect failed: %s\n", $mysqli->connect_error);
exit();
}
$title = $_POST['title'];
$author = $_POST['author'];
$content = $_POST['content'];
$action = $_POST['action_type'];
$blog_id = $_GET['blog_id'];
function save()
{
$insert_query = "INSERT INTO tb_blogs (`title`, `author` , `content`) values ('{$title}','{$author}','{$content}')";
$mysqli->query($insert_query);
}
function update()
{
$update_query = "UPDATE tb_blogs SET `title` = '{$title}', `author` = '{$author}', `content` = '{$content}' WHERE id = '{$blog_id}'";
$mysqli->query($update_query);
}
if(isset($_POST["submit"])) {
if($action=='create') {
save();
}
elseif($action=='update') {
update();
}
}
I know this has been marked as answered, but I think it's important to show a bind parameter example. This is a bit more complex of a solution, mind you, but it's fairly organized so it should be fairly easy to dissect. Also this is just an example, there are many ways to do this script with bind parameters. The bind parameters in the functions is the most important part really:
/classes/class.DatabaseConfig.php
<?php
// Database configuration meant for connection
class DatabaseConfig
{
private static $singleton;
public function __construct()
{
if(empty(self::$singleton))
self::$singleton = $this;
return self::$singleton;
}
public function connectMySQLi($host = "localhost", $username = "username", $password = "password", $database = "database")
{
// Create connection
try {
$mysqli = new mysqli($host, $username, $password, $database);
return $mysqli;
} catch (mysqli_sql_exception $e) {
// Print real error if admin, or write to
// secured log file
// throw $e;
die("Connection has failed.");
}
}
}
/classes/class.Db.php
<?php
// Singleton-based class to re-use instantiated resources
class Db
{
private static $singleton;
// Default connection
public static function mysqli()
{
if(empty(self::$singleton)) {
$con = new DatabaseConfig();
self::$singleton = $con->connectMySQLi();
}
return self::$singleton;
}
}
/functions/function.save.php
<?php
// I have chosen a singleton, but you can pass your db connection as a
// second argument like save($array,$mysqli)
function save($settings = false)
{
// Because the the class allows for a static variable, you can
// connect straight in the class without using globals
$mysqli = Db::mysqli();
// Use bind_param/prepare/execute for safe queries
$stmt = $mysqli->prepare("INSERT INTO `tb_blogs` (`title`, `author` , `content`) values (?,?,?)");
// You can do checks on these variables to see that they are filled out, I have not though
$stmt->bind_param("sss",$settings['title'],$settings['author'],$settings['content']);
$stmt->execute();
}
/functions/function.update.php
<?php
function update($settings = false)
{
$mysqli = Db::mysqli();
$stmt = $mysqli->prepare("UPDATE `tb_blogs` SET `title` = ?, `author` = ?, `content` = ? WHERE id = ?");
$stmt->bind_param("sssi",$settings['title'],$settings['author'],$settings['content'],$settings['blog_id']);
$stmt->execute();
}
index.php
<?php
// Look into using spl_autoload_register() here
include_once("classes/class.DatabaseConfig.php");
include_once("classes/class.Db.php");
// You can make a similar autoloader-type function as well instead of
/// manually writing a crap-load of includes
include_once("functions/function.save.php");
include_once("functions/function.update.php");
// Do single wrapper for submit
if(isset($_POST['submit'])) {
// Check for create
if($_POST["action_type"] =='create')
save($_POST);
// Check for update
elseif($_POST["action_type"] =='update')
update($_POST);
}

My first database connection

I've bought a domain-hosting from a local company. Their customer service is pretty horrible.
My code for connecting to the database seems ok but still its not working. Here my code:
function __construct(){
if(!#mysql_ping()){
$this->db_connect();
}
$sql = "SELECT value FROM settings WHERE field = 'auto_logout'";
$res = mysql_fetch_array($this->execute_single_query($sql));
$this->LOGIN_DURATION = $res['value'];
}
private function db_connect(){
// Mysql connect
$link = #mysql_connect('localhost', 'created_who_has_all_prev', 'pass_note_my_cpanel_and_mysql_has_same_pass');
if (!$link) {
die('Could not connect: ' . mysql_error());
}
//echo 'Connected successfully<br/>';
// Mysql select db select --->
$db_selected = mysql_select_db($this->DB, $link);
if (!$db_selected) {
die ('Can\'t use specified Database : ' . mysql_error());
}
//echo "<br/>Database Selected<br/>";
return $link;
}
And this is the snapshot:
Your main problem is that the link that you create isn't accessible. So, PHP tries to connect with defaults (apparently in your setup it means the user is root) and since it has no password, the connection fails which is the cause of most of your warning messages.
The last warning is a consequence of the others.
To fix this problem - as you haven't provided details of the actual parts that are executing the query - here is how to re-write your code so it works:
$mysqli = new mysqli("localhost", "user", "password", "database");
if ($mysqli->connect_errno) {
echo "(".$mysqli->connect_errno.") ".$mysqli->connect_error;
}
$sql = "SELECT `value` FROM `settings` WHERE `field` = ?";
$stmt = $mysqli->prepare($sql);
$stmt->bind_param("s","auto_logout");
if (!$stmt->execute()) {
echo "(".$stmt->errno.") ".$stmt->error;
}
$res = $stmt->get_result();
$row = $res->fetch_assoc();
LOGIN_DURATION = $row['field'];
This is really sloppy code. I would use PDO as it is secure. Below is a class you can use but study how it works and why it works.
class Core {
public $dbh; // handle of the db connection
private static $instance;
private function __construct() {
$options = array(PDO::ATTR_PERSISTENT => true, PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION);
$this->dbh = new PDO("mysql:host=localhost;dbname=dealership", "root", "",$options);
}
public static function getInstance() {
if (!self::$instance) {
self::$instance = new self();
}
return self::$instance;
}
private function __clone() {}
private function __wakeup() {}
}
In your code call it like below:
require "/classes/pdo.class.php";
$db = Core::getInstance();
$stmt = "SELECT `lastname` FROM `employees` where id = 2";
$pep = $db->dbh->prepare($stmt);
$pep->execute();
foreach($pep->fetchAll(PDO::FETCH_ASSOC) as $row) {
echo $row['lastname']. "\n";
}
Make sure you look into PDO, prepared statments, and singleton pattern to understand why it works.

PHP undefined variable that should clearly be defined

I am wondering how $link can be undefined. It is a global inside class cdb.php and is set when the mysql connect is called. If it were undefined, when mysql connect was called, it would die because I have coded it this way.
<html>
<head>
</head>
<body>
<?php
function justGetCSNumbers($input)
{
$input = preg_replace('/[\D]/',"",$input);
$sp = preg_split("/,/",$input);
$numbs = preg_grep('/^(\d+)(,\d+)*$/',$sp);
$csv = implode(",",$numbs);
#echo $csv;
return $csv;
}
function queryDB($cleaned)
{
$split = preg_split('/,/',$cleaned);
$resAy = array();
for($i=0;$i<count($split);$i++)
{
if((strlen($split[$i])>5)&&(strlen($split[$i])<10))
{
$resAy[$i] = "uid='$split[$i]'";
}
}
if(count($resAy)>0)
{
$q = 'SELECT * FROM userbase WHERE '.$resAy[0];#.$whereclause;
echo '<br/> query: '.$q.'<br/>';
connectDB();
return mysql_query($q,$link) or die("Couldn't complete query ".mysql_error($link));
}
}
function find(){
$p = $_POST['userToQuery'];
if(isset($p))
{
$csv = justGetCSNumbers($p);
$found= queryDB($csv);
}
}
include('cdb.php');
find();
?>
Sorry for the poorly formatted code, using vi.
My apache2 error log shows that the variable $link is undefined when i use it here, even after calling connectDB(); which is the code that does a mysql_connect and therefore sets up the link.
'mysql_error() expects parameter 1 to be resource, null given'
I refactored my code so the link would be defined (this version), but somehow I am having trouble.
[EDIT]
Here is the cdb.php class:
<?php
function connectDB()
{
global $link;
$uname = 'site123';
$pass = 'abc123';
$loc = "localhost";
$link = mysql_connect($loc, $uname, $pass) or die("Couldn't connect to the DB");
$dbname = 'jagrail';
$db = mysql_select_db($dbname,$link);
if(!$db)
{die("Failed to select db");}
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
}
#return $link;
}
?>
EDIT:
Add:
global $link;
to the top of the queryDB() function, so that it knows $link is a global variable, rather than just a local.

Categories