counting rows and passing information with mysqli - php

I have been trying to convert a php page to mysqli, and have encoutnered some problems. Given the code below, and the way which I have ordered things to work, I would like to know what the better way is using mysqli methods.
Is there an mysqli alternative to mysql_num_rows or is a different method of calculating the number of rows required?
How would I do the following using mysqli?:
$data = mysql_query($countQuery) or die(mysql_error());
$rowcount = mysql_num_rows($data);
What is an alternative for mysql_fetch_assoc? I feel that I should not be using the current rows method I am using, even if there is a replacement function, so what would be the correct approach?
I apologize for these questions, but I have not been able to determine the answers myself so far.
<?php
$con = mysqli_connect("localhost", "user", "", "ebay");
if (!$con) {
echo "Can't connect to MySQL Server. Errorcode: %s\n". mysqli_connect_error();
exit;
}
$con->query("SET NAMES 'utf8'");
$cmd = "word";
//normally retrieved from GET
if($cmd=="deleterec") {
$deleteQuery = "DELETE FROM AUCTIONS1 WHERE ARTICLE_NO = ?";
if ($delRecord = $con->prepare($deleteQuery)) {
$delRecord->bind_param("s", $pk);
$delRecord->execute();
}
}
$table = 'AUCTIONS';
$brand = "test";
$countQuery = "SELECT ARTICLE_NO FROM ? WHERE upper(ARTICLE_NAME) LIKE '% ? %'";
if ($numRecords = $con->prepare($countQuery)) {
$numRecords->bind_param("ss", $table, $brand);
$numRecords->execute();
$data = $con->query($countQuery) or die(print_r($con->error));
$rowcount = mysql_num_rows($data);
$rows = getRowsByArticleSearch($query, $table, $max);
$last = ceil($rowcount/$page_rows);
}
$self = htmlspecialchars($_SERVER['PHP_SELF'],ENT_QUOTES,'utf-8');
foreach ($rows as $row) // print table rows {
echo '<tr>' . "\n";
echo '<td>'.$row['USERNAME'].'</td>' . "\n";
// repeated for each column
}
function getRowsByArticleSearch($searchString, $table, $max) {
global $con;
$recordsQuery = "SELECT ARTICLE_NO, USERNAME, ACCESSSTARTS, ARTICLE_NAME, date_format(str_to_date(ACCESSSTARTS, '%d/%m/%Y %k:%i:%s'), '%d %m %Y' ) AS shortDate FROM ? WHERE upper(ARTICLE_NAME) LIKE '%?%' ORDER BY str_to_date(ACCESSSTARTS, '%d/%m/%Y %k:%i:%s')" . $max;
if ($getRecords = $con->prepare($recordsQuery)) {
$getRecords->bind_param("ss", $searchString, $table);
$getRecords->execute();
$getRecords->bind_result($ARTICLE_NO, $USERNAME, $ACCESSSTARTS, $ARTICLE_NAME, $shortDate);
while ($getRecords->fetch()) {
$result = $con->query($recordsQuery);
$rows = array();
while($row = mysql_fetch_assoc($result)) {
$rows[] = $row;
}
return $rows;
}
}
}

I usually use this directly after my execute:
$query->execute();
// store the result first
$query->store_result();
$rows = $query->num_rows;

Actually, to answer the first question:
$data = mysql_query($countQuery) or die(mysql_error());
$rowcount = mysql_num_rows($data);
If you want to do this using mysqli, mysqli_num_rows works just fine. The only difference is, remember to put the connection parameter in the query.
$data = mysqli_query($dbc,$countQuery) or die(mysql_error());

I've rewritten your code sample with the correct property / function calls to fix the two issues that you mention in the question:
<?php
$con = mysqli::connect("localhost", "user", "", "ebay");
if (!$con) {
echo "Can't connect to MySQL Server. Errorcode: %s\n". mysqli_connect_error();
exit;
}
$con->query("SET NAMES 'utf8'");
$cmd = "word";
//normally retrieved from GET
if($cmd=="deleterec") {
$deleteQuery = "DELETE FROM AUCTIONS1 WHERE ARTICLE_NO = ?";
if ($delRecord = $con->prepare($deleteQuery)) {
$delRecord->bind_param("s", $pk);
$delRecord->execute();
}
}
$table = 'AUCTIONS';
$brand = "test";
$countQuery = "SELECT ARTICLE_NO FROM ? WHERE upper(ARTICLE_NAME) LIKE '% ? %'";
if ($numRecords = $con->prepare($countQuery)) {
$numRecords->bind_param("ss", $table, $brand);
$numRecords->execute();
$data = $con->query($countQuery) or die(print_r($con->error));
// Here is the property that you can reference to determine the affected rows from the previous query. -- gabriel
$rowcount = $data->num_rows;
$rows = getRowsByArticleSearch($query, $table, $max);
$last = ceil($rowcount/$page_rows);
}
$self = htmlspecialchars($_SERVER['PHP_SELF'],ENT_QUOTES,'utf-8');
foreach ($rows as $row) // print table rows {
echo '<tr>' . "\n";
echo '<td>'.$row['USERNAME'].'</td>' . "\n";
// repeated for each column
}
function getRowsByArticleSearch($searchString, $table, $max) {
//global $con; Globals are BAD!! Please don't use.
$con = mysqli::connet("localhost", "user", "", "ebay");
$recordsQuery = "SELECT ARTICLE_NO, USERNAME, ACCESSSTARTS, ARTICLE_NAME, date_format(str_to_date(ACCESSSTARTS, '%d/%m/%Y %k:%i:%s'), '%d %m %Y' ) AS shortDate FROM ? WHERE upper(ARTICLE_NAME) LIKE '%?%' ORDER BY str_to_date(ACCESSSTARTS, '%d/%m/%Y %k:%i:%s')" . $max;
if ($getRecords = $con->prepare($recordsQuery)) {
$getRecords->bind_param("ss", $searchString, $table);
$getRecords->execute();
$getRecords->bind_result($ARTICLE_NO, $USERNAME, $ACCESSSTARTS, $ARTICLE_NAME, $shortDate);
while ($getRecords->fetch()) {
$result = $con->query($recordsQuery);
$rows = array();
// Notice the adjusted function call to retrieve the associate array for each record within the result set. -- gabriel
while($row = $result->fetch_assoc()) {
$rows[] = $row;
}
return $rows;
}
}
}
However, I would like to add that dusoft was correct in the assessment that MySQLi is buggy and is known to create issues. It is for this reason that we had to switch from MySQLi to PDO (which is native to PHP as of at least 5.1) and we haven't had any problems since. I would strongly recommend that you look at PDO or perhaps one of the Pear libraries to actually provide your database connection interface.

You can use:
$data->num_rows();
$data->fetch_assoc();
You can check out the docs for more info num_rows and fetch_assoc.

Related

Error Using mysqli_data_seek when using Do While Procedure [duplicate]

I cannot get my Mysqli queries to both work. If I comment out one function in my html, the other function is properly executed and vice versa.
function all_posts() {
require_once 'database.inc.php';
$mysqli = mysqli_connect($host, $username, $password, $database);
$query = mysqli_query($mysqli, "SELECT variable_name, post_name, post_date, post_display FROM blog_posts ORDER BY id DESC LIMIT 5");
if (!$query)
echo mysqli_error();
while ($results = mysqli_fetch_assoc($query)) {
$post_name = $results['post_name'];
$post_date = $results['post_date'];
$post_display = $results['post_display'];
$variable_name = $results['variable_name'];
echo "<a href='posts.php?post={$variable_name}'>";
echo "<div class='entry'>";
echo "<div class='entry_header'>";
echo "<h2>{$post_name}</h2>";
echo "<h3>{$post_date}</h3>";
echo "</div>";
echo "<p>{$post_display}</p>";
echo "</div>";
echo "</a>";
}
mysqli_free_result();
}
function all_sidebar_posts() {
require_once 'database.inc.php';
$mysqli = mysqli_connect($host, $username, $password, $database);
$query = mysqli_query($mysqli, "SELECT variable_name, post_name FROM blog_posts ORDER BY id DESC LIMIT 5");
while ($results = mysqli_fetch_assoc($query)) {
$post_name = $results['post_name'];
$variable_name = $results['variable_name'];
echo "<li><a href='posts.php?post=$variable_name'>$post_name</a></li>";
}
mysqli_free_result();
}
Here is the html that I am outputting to.
<ul>
<?php all_sidebar_posts(); ?>
</ul>
</div>
<div class="content_container">
<?php all_posts(); ?>
</div>
I have tried using mysqli_data_seek(); but haven't had luck. Perhaps I am not using it right? I have browsed many questions and found similar ones but I have tried them all to no avail. I am new to programming so I may be overlooking something basic. Thank you all for the help!
You are doing it wrong way.
Never mix your data manipulation code with presentation code.
First, get the posts into array:
require_once 'database.inc.php';
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$mysqli = mysqli_connect($host, $username, $password, $database);
$sql = "SELECT variable_name, post_name, post_date, post_display
FROM blog_posts ORDER BY id DESC LIMIT 5"
$result = mysqli_query($mysqli, $sql);
$data = array();
while ($row = mysqli_fetch_assoc($result)) {
$data[] = $row;
}
and then use this $data array to display posts any times you need, simply using foreach()
http://www.php.net/manual/en/mysqli-result.data-seek.php
Consult the manual for the usage of data_seek();
Take this example:
$Query = "SELECT * FROM Users WHERE ID='1'";
$TheQuery -> $MySQLi->query($Query);
$Results = $TheQuery->fetch_array(MYSQLI_ASSOC);
$TheQuery->data_seek(0); // Lets you re-use the query
$Count = $TheQuery->num_rows; // Gets the count
so in your case:
You should perform the procedure method:
$query = "SELECT Name, CountryCode FROM City ORDER BY Name";
if ($result = mysqli_query($link, $query)) {
/* fetch row */
$row = mysqli_fetch_row($result);
printf ("City: %s Countrycode: %s\n", $row[0], $row[1]);
mysqli_data_seek($result, 0);
$row_cnt = mysqli_num_rows($result);
/* free result set*/
mysqli_free_result($result);
}

How to write MySQL query in prepare method when search?

how can I secure my search query with the prepare method?
DB Connection
// connect to database
$con = new mysqli("localhost", "root", "", "chat");
// Check connection
if ($con->connect_error) {
die("Connection failed: " . $con->connect_error);
}
MySQL Query
if (isset($_POST['query'])) {
$search_string = trim($_POST['query']);
$query = mysqli_real_escape_string($con, $search_string);
//MySQL order by best match
$sql = "SELECT reply FROM question_answer WHERE question
LIKE '%$query%'
ORDER BY CASE
WHEN question = '$query' THEN 0
WHEN question LIKE '$query%' THEN 1
WHEN question LIKE '%$query%' THEN 2
WHEN question LIKE '%$query' THEN 3
ELSE 4
END, question ASC";
$res = mysqli_query($con, $sql);
if (mysqli_num_rows($res) > 0) {
$row = mysqli_fetch_assoc($res);
$html = $row['reply'];
} else {
$html = "Sorry not be able to understand you";
$added_on = date('Y-m-d h:i:s');
mysqli_query($con, "INSERT INTO unknown_question(question,added_on,type) VALUES('$query','$added_on','user')");
}
echo $html;
die();
}
An example of using prepared queries with mysqli in your code could be like this:
if (isset($_POST['query'])) {
$sql = "SELECT reply FROM question_answer WHERE question LIKE ?
ORDER BY CASE
WHEN question = ? THEN 0
WHEN question LIKE ? THEN 1
WHEN question LIKE ? THEN 3
ELSE 2
END, question ASC";
$query = trim($_POST['query']);
$params = [
'%' . $query . '%',
$query,
$query . '%',
'%' . $query
];
$stmt = $con->prepare($sql);
$stmt->bind_param(str_repeat('s', count($params)), ...$params);
$stmt->execute();
$result = $stmt->get_result();
$row = $result->fetch_assoc();
if (!empty($row)) {
$html = $row['reply'];
} else {
$html = "Sorry not be able to understand you";
$added_on = date('Y-m-d h:i:s');
$sql = "INSERT INTO unknown_question(question,added_on,type) VALUES(?,?,'user')";
$stmt = $con->prepare($sql);
$stmt->bind_param('ss', $query, $added_on);
$stmt->execute();
}
echo $html;
}

Select Query with OOP PHP ORM

for a customer I have to make little adjustments to an application what is build on OOP PHP. I have no experience at all with OOP, and normally I only use PHP for small functions. I would like to select data from my database, to use it in a build function and variable. My code under will explain
public function readTwitter(){
$accounts = array();
$hastags = array('coldplay');
\ORM::for_table('feed_items')->where('portal_reference', 'tw')->delete_many();
foreach($accounts as $account) {
$feed = $this->twitter->getFeedByAccount($account);
foreach($feed as $post){
$this->twitter->savePost($post);
}
}
foreach($hastags as $hashtag) {
$feed = $this->twitter->getFeedByHashtag($hashtag);
foreach($feed->statuses as $post){
$this->twitter->savePost($post);
}
}
}
So in this version of the application the foreach loop will check if the var is filled in, what is now done with an array, and use it in the function readTwitter() What I like to have is a select query which selects one specific row out of my database to use it instead of an array, written in my application as OOP as follow (written in procedural php):
$dbCon = mysqli_connect("localhost", "root", "root", "database");
if (mysqli_connect_errno()) {
echo "Failed to connect: " . mysqli_connect_error();
}
$sql = "SELECT * FROM `questions` WHERE `location` = 'wall' ORDER BY `questions`.`id` DESC ";
$query = mysqli_query($dbCon, $sql);
if ($query) {
$row = mysqli_fetch_row($query);
$hashtags = $row[2]; //instead of array('coldplay');
}
public function readTwitter(){
$dbCon = mysqli_connect("localhost", "root", "root", "database");
if (mysqli_connect_errno()) {
echo "Failed to connect: " . mysqli_connect_error();
}
$sql = "SELECT * FROM `vragen` WHERE `location` = 'wall' ORDER BY `vragen`.`id` DESC ";
$query = mysqli_query($dbCon, $sql);
if ($query) {
$row = mysqli_fetch_row($query);
$accounts = $row[3];
$hashtags = $row[2];
\ORM::for_table('feed_items')->where('portal_reference', 'tw')->delete_many();
$feed = $this->twitter->getFeedByAccount($accounts);
foreach($feed as $post){
$this->twitter->savePost($post);
}
$feed = $this->twitter->getFeedByHashtag($hashtags);
foreach($feed->statuses as $post){
$this->twitter->savePost($post);
}
}
}
I have tried to combine the code and it works like I want, but I dont think this is the right way for OOP, right?

How to from Old Query PHP to Query with Prepared Statements with PDO PHP

Iam bringing my old code (vunerable in so many ways) to new standards with PDO.
The problem is, i'm getting no return, no error message, no nothing.
What my code do is the following: Makes a query to the DB and if there is any result ($resultado) it creates an order of the data in arrays.
Can please someone give me a help?
I tried the Array approach and the Object approach, no donuts :/
Old Code:
$sql_code =
"SELECT news_id, news_title, news_date, news_resume
FROM news
WHERE news_show = 'S'
ORDER BY news_date DESC
";
$result = mysql_query($sql_code);
if ($result) {
$rows = mysql_num_rows($result);
for ($i=0; $i<$rows; $i++) {
$aID[] = mysql_result($result, $i, "news_id");
$aTitle[] = mysql_result($result, $i, "news_title");
$aDate[] = mysql_result($result, $i, "news_date");
$aResume[] = mysql_result($result, $i, "news_resume");
}
}
?>
New Code that doesnt work:
try
{
$dbh = new PDO("mysql:host=$dbhost;dbname=$dbname", $dbuser, $dbpasswd);
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$stmt = $dbh->prepare("SELECT news_id, news_title, news_date, news_resume
FROM news
WHERE news_show = :newsS
ORDER BY news_date DESC");
$stmt->execute(array('newsS' => 'S'));
while ($sql_code = $stmt->fetchall(PDO::FETCH_ASSOC))
{
$result = mysql_query($sql_code);
}
}
catch(PDOException $e)
{
echo "Error:". $e->getMessage();
}
$result = mysql_query($sql_code);
if ($result)
{
$rows = mysql_num_rows($result);
for ($i=0; $i<$rows; $i++)
{
$aID[] = mysql_result($result, $i, "news_id");
$aTitle[] = mysql_result($result, $i, "news_title");
$aDate[] = mysql_result($result, $i, "news_date");
$aResume[] = mysql_result($result, $i, "news_resume");
}
}
?>
If you're using PDO, you don't call any mysql_XXX functions, you have to use PDO methods for everything.
$stmt->fetchAll() returns all the rows of the results. To process it, just use a foreach loop.
try
{
$dbh = new PDO("mysql:host=$dbhost;dbname=$dbname", $dbuser, $dbpasswd);
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$stmt = $dbh->prepare("SELECT news_id, news_title, news_date, news_resume
FROM news
WHERE news_show = :newsS
ORDER BY news_date DESC");
$stmt->execute(array('newsS' => 'S'));
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
foreach ($result as $row) {
$aId[] = $row['news_id'];
$aTitle[] = $row['news_title'];
$aDate[] = $row['news_date'];
$aResume[] = $row['news_resume'];
}
}
catch(PDOException $e)
{
echo "Error:". $e->getMessage();
}

Returning Multiple Rows with MySqli and Arrays

For the past two days or so I've been converting my functions to mysqli. I've run into a problem. I have a function that returns an array containing a row from the database. However, I want the array to contain multiple rows versus one. Also, how would I be able to echo out the individual posts. Here is my failed attempt that only displays one row in the array.
$mysqli = new mysqli("localhost", "user", "password", "database");
function display_posts ($mysqli, $user_id) {
$fields = "`primary_id`, `poster_id`, `profile_user_id`, `post`";
$user_id = (int)$user_id;
$query = "SELECT DISTINCT $fields FROM `posts` WHERE `profile_user_id` = $user_id
LIMIT 4";
if ($result = $mysqli->query($query)) {
$row = $result->fetch_assoc();
return $row;
$result->free();
$stmt->close();
}}
Here I am trying to display the data.
$user_id = 1;
$posts = display_posts($mysqli, $user_id);
//Not sure what to do with $posts. A While loop perhaps to display each post?
You have to use a loop to get them all at once:
<?php
function resultToArray($result) {
$rows = array();
while($row = $result->fetch_assoc()) {
$rows[] = $row;
}
return $rows;
}
// Usage
$query = 'SELECT DISTINCT $fields FROM `posts` WHERE `profile_user_id` = $user_id LIMIT 4';
$result = $mysqli->query($query);
$rows = resultToArray($result);
var_dump($rows); // Array of rows
$result->free();
Why not use directly like this:
$result = mysqli_fetch_all($mysqli->query($query), MYSQLI_ASSOC);
I'm late, but I believe this is what you wanted to achieve:
$mysqli = new mysqli("localhost", "user", "password", "database");
$fields = "`primary_id`, `poster_id`, `profile_user_id`, `post`";
function display_posts () {
global $mysqli;
global $fields;
$query = "SELECT DISTINCT $fields FROM `posts` WHERE `profile_user_id` = $user_id LIMIT 4";
$posts = $mysqli -> query($query) or die('Error: '.$mysqli -> error);
if ($posts -> num_rows > 0) {
while ($row = $posts -> fetch_assoc()) {
$value = $row['/*The table column here (You can repeat this line with a different variable e.g. $value 2, $value 3 etc and matching them with the respective table column)*/'];
echo $value./*Concatenate the other variables ($value 1 etc) here*/'<br />';
}
}else {
echo 'No records found.';
}
}
//Call the function
display_posts ();

Categories