Fetch array using both if and while doesn't work - php

Basically I have 2 methods in the same class, getMovie and getGenres. They are very similar but One doesn't return what I expect.
Here's getMovie method:
public function getMovie($argType, $arg){
$movieQuery = "SELECT id,
rt_id,
imdb_id,
url,
rt_url,
type,
adult,
DATE_FORMAT(release_date, '%Y') AS year,
date_added,
title,
runtime,
budget,
revenue,
homepage,
rating,
tagline,
overview,
popularity,
image,
backdrop,
trailer
FROM movies
WHERE " . $argType . " = " . $arg;
$movieResult = $this->_query($movieQuery);
$movies = array();
if($movieResult->fetch_array(MYSQLI_ASSOC)){
while($m = $movieResult->fetch_array(MYSQLI_ASSOC)){
$movies[] = array( 'title' => $m['title'],
'duplicate' => $m['duplicate'],
'url' => $m['url'],
'rt_url' => $m['rt_url'],
'release_date' => $m['release_date'],
'date_added' => $m['date_added'],
'type' => 'movie',
'adult' => $m['adult'],
'id' => $id,
'rt_id' => $m['rt_id'],
'imdb_id' => $m['imdb_id'],
'rating' => $m['rating'],
'tagline' => $m['tagline'],
'overview' => $m['overview'],
'popularity' => $m['popularity'],
'runtime' => $m['runtime'],
'budget' => $m['budget'],
'revenue' => $m['revenue'],
'homepage' => $m['homepage'],
'image' => $m['image'],
'backdrop' => $m['backdrop'],
'trailer' => $m['trailer'] );
}
return $movies;
}
else{
return false;
}
Here's getGenres method:
public function getGenres($movieId = NULL){
$genresQuery = "";
if($movieId != NULL){
$genresQuery = "SELECT id,
name
FROM genres
WHERE id = ANY (
SELECT genre_id
FROM movie_genres
WHERE movie_id = " . $movieId . ")";
}
else{
$genresQuery = "SELECT id,
name
FROM genres";
}
$genresResult = $this->_query($genresQuery);
$genres = array();
if($genresResult->fetch_array(MYSQLI_ASSOC)){
while($genre = $genresResult->fetch_array(MYSQLI_ASSOC)){
$genres[] = array( 'id' => $genre['id'],
'name' => $genre['name'] );
}
return $genres;
}
else{
return false;
}
}
And here's how I call them:
$mov = $movie->getMovie(2207);
print_r($mov); // output: Array()
$gen = $movie->getGenres(2207);
print_r($gen); // output: Array(values inside)
Both queries do actually return expected values but getMovies method doesn't work with the if statement. It works fine if I just have while loop.
I am using if as well as while as I heard that while loop can sometimes execute even when there's not values. Is there any truth to this? If there is indeed a reason to use an if statement as well as wile loop then why doesn't it work with getMovies method?
Edit 1: I tried storing the array like so but that resulted in a memory related error:
$r = $genresResult->fetch_array(MYSQLI_ASSOC);
if($r){
while($r){
$genres[] = array( 'id' => $genre['id'],
'name' => $genre['name'] );
}
return $genres;
}

I am using if as well as while as I heard that while loop can sometimes execute even when there's not values. Is there any truth to this?
No, according to the php manual mysqli_result::fetch_array returns an array of strings that corresponds to the fetched row or NULL if there are no more rows in resultset.
Null is falsy so the while loop will not be entered.
Although the if statement is unnecessary if you had one you would use mysqli_result::$num_rows to check if the query returned any rows.
if($movieResult->num_rows > 0){
while($m = $movieResult->fetch_array(MYSQLI_ASSOC)){
...
}
}

Related

How to fix "Call to a member function execute() on string" on my function

I'm modifying a Wordpress API witch is currently getting learnpress course and lessons infos from the database using leanrpress functions only. I need to modify the API to get the scores from the newly implemented plugin h5p, therefor i need to make a new function to access the Database and get the scores from the right table, then put then into an array with the according lesson. The array here is only an exemple i'm using to see if i can get the datas, ut i'm stuck with the error
"Call to a member function execute() on string"
when i try and run it on postman. Could someone lighten me on this issue please ?
function ilp_api_get_progress_by_mail($data){
$mail=$_GET['mail']; //$data->get_param["mail"];
$course_id=$_GET['course'];
global $wpdb;
$user=get_user_by("email",$mail);
if($user !== false){
$lp_user=learn_press_get_user( $user->ID );
if($course_id==NULL){
$all_courses=ilp_api_get_all_courses($data);
}else{
$all_courses=array('courses' => array(array('id' => intval($course_id))));
}
$progress=array();
$i=0;
if($all_courses!=NULL && $all_courses['courses']!=null){
foreach($all_courses['courses'] as $course){
if($lp_user->has_enrolled_course($course['id'])){
$lp_course=learn_press_get_course( $course['id'] );
$course_data = $lp_user->get_course_data($course['id']);
$course_results = $course_data->get_results( false );
$progress[$i]=array(
'id' => $course['id'],
'name' => $lp_course->get_title(), //$course['name'],
'condition' => $lp_course->get_passing_condition(),
'completed' => $course_results['completed_items'],
'total' => $course_results['count_items'],
'progress' => absint( $course_results['completed_items'] / $course_results['count_items'] * 100 ),
'permalink' => $lp_course->get_permalink(),
);
$i++;
}
}
}
$result = array(
'userfound' => true,
'user_id' => $user->ID,
'connect' => get_h5p_grades(),
'courses_progress' => $progress,
'course_id' => $all_courses,
);
function get_h5p_grades(){
global $wpdb;
$ID = 1;
$ID_use = 1;
$result = $wpdb->prepare('SELECT score FROM mci_h5p_results WHERE id = %d AND user_id = %d', $ID, $ID_use);
$result->execute();
$donnees = $result->fetch();
return $donnees;
}

Use a generated string for an array in MySQL with variables

I need to use a generated string as an array within a MySQL-Loop.
The string/array is built into $argumentarray from the $rows arguments and should after be used as the array of multiSQLarray[]
The function is called as:
multiSQL('**id,title,description,link**','menu')
The string gets correctly generated as
array('id' => $result['id'],'title' => $result['title'],'description' => $result['description'], 'link' => $result['link'])
But instead of using it as a string for the array it just adds it to the array for every result from the sql
Array ( [0] => array('id' => $result['id'],'title' => $result['title'],'description' => $result['description'], 'link' => $result['link']) [1] => array('id' => $result['id'],'title' => $result['title'],'description' => $result['description'], 'link' => $result['link']) )
What i expect is the SQL result as the array
Array ( [0] => Array ( [id] => 1 [title] => Customers [description] => Display the Customer Dashboard [link] => index.php ) [1] => Array ( [id] => 2 [title] => Server [description] => Display all Servers [link] => servers.php ) )
My code:
function multiSQL($rows=null,$table=null,$select=null) {
if(is_null($select)) {$filter="";} else { $filter = ' where '.$select; }
global $pdo;
$sql = 'SELECT '.$rows.' FROM '.$table.$filter.'';
$connection =$pdo->prepare($sql);
$connection->execute();
$multiSQLarray = array();
$arguments = explode(',',$rows);
$argumentarray = "";
$argumentscount=count($arguments);
$loopcount = 1;
foreach($arguments as $argument){
if($loopcount==$argumentscount){
$loopcount++;
$argumentarray = $argumentarray.' \''.$argument.'\' => $result[\''.$argument.'\']';
}
else{
$loopcount++;
$argumentarray = $argumentarray.'\''.$argument.'\' => $result[\''.$argument.'\'],';
}
}
$argumentarray = 'array('.$argumentarray.')';
echo $argumentarray.'<br><br>';
while ($result = $connection->fetch(PDO::FETCH_BOTH)) {
//$multiSQLarray[] = array('id' => $result['id'], 'title' => $result['title'], 'description' => $result['description'], 'link' => $result['link']);
$multiSQLarray[] = $argumentarray;
}
print_r($multiSQLarray);
return $multiSQLarray;
Structured data is structured data. Be it in a string or an array. I can't make sense of some of your code. The arrays in strings... unless you are angling to use an eval. I think that bit confuses your question some.
One thing you need to consider is how exposed you will be to SQL injection. Basically never trust the user right? So, you could do things like predfine, in code, the allowed columns. If the form submitted references something not whitelisted then stop! Also, have to think about escaping the user supplied values.
I'd want my function to accept a known, arguments that make sense for what it needs passed in... Clean things up first and then pass some data types that make the most sense to the function. Maybe something like...
/**
* #param string $table
* #param array $fields
* #param array $criteria (key/value pairs where key is field and value is scalar)
*/
function buildQuery($table, $fields, $criteria) {
$where = [];
$whereVals = [];
foreach($criteria as $k => $v) {
$where[] = "({$k} = ?)";
$whereVals[] = $v;
}
$where = implode(' AND ', $where);
$fields = implode(', ', $fields);
$sql = "SELECT {$fields} FROM {$table} WHERE {$where}";
//eg. SELECT id, name, bar FROM fooTable WHERE (id = ?) AND (name = ?)
$query = $pdo->prepare($sql);
$retval = $query->execute($whereVals);
return $retval;
}
$response = buildQuery( 'fooTable',
['id', 'name', 'bar'],
[
'id' => 5,
'name' => 'john'
]);
Maybe look at some frameworks or an ORM like Doctrine? Can see some good examples of OOP representations of a select statement. Makes dynamic query building a lot easier. End up with something DRYer too.

How to create multiple conditioner login in codeigniter

my model is here.....but i need to select status of admin ....... but
i m new in codeigniter....and don't no how to select... my need is...
select admin whole detail from table on condition admin status =
active and id=1...
my model is :
public function login($value) {
$query = $this->db->get_where('tbl_admin', $value, 1, 'active');
if ($query->num_rows() > 0) {
$row = $query->row_array();
$sess_arr = array(
'admin_user' => $row['fld_admin_username'],
'adm_key' => $row['fld_admin_key'],
'admin_type' => $row['fld_admin_type'],
'admin_id' => $row['fld_admin_id'],
'admin_logged_in' => TRUE
);
$this->session->set_userdata($sess_arr);
//echo "<pre>";print_r($this->session->all_userdata());exit;
}
else{
$this->session->set_flashdata('error', 'Invalid username/password');
redirect('adminzone');
}
}
The correct syntax for the first line would be:
$query = $this->db->get_where('tbl_admin', array('id' => 1, 'status' => 'active'));
I.e. The second parameter to get_where is an associative array of fields and their values..
Edit: Or perhaps it should be
$query = $this->db->get_where('tbl_admin', array('id' => $value, 'status' => 'active'));
(I am not sure what the $value variable is for here).

How can I fix this query to return only items with a certain value in its subarray?

I'm trying to modify a voting script(Thumbsup) I need this query to only return only array items that have their 'cat' => '1' in the subarray (proper term?)
<?php $items = ThumbsUp::items()->get() ?>
Here's an example of the live generated array from my database
array (
0 =>
array (
'id' => 1,
'name' => 'a',
'cat' => '1',
),
1 =>
array (
'id' => 2,
'name' => 'b',
'cat' => '2',
),
2 =>
array (
'id' => 3,
'name' => 'c',
'cat' => '2',
),
)
Is this possible by just modifying the query?
edit: heres function get()
public function get()
{
// Start building the query
$sql = 'SELECT id, name, url, cat, closed, date, votes_up, votes_down, ';
$sql .= 'votes_up - votes_down AS votes_balance, ';
$sql .= 'votes_up + votes_down AS votes_total, ';
$sql .= 'votes_up / (votes_up + votes_down) * 100 AS votes_pct_up, ';
$sql .= 'votes_down / (votes_up + votes_down) * 100 AS votes_pct_down ';
$sql .= 'FROM '.ThumbsUp::config('database_table_prefix').'items ';
// Select only either open or closed items
if ($this->closed !== NULL)
{
$where[] = 'closed = '.(int) $this->closed;
}
// Select only either open or closed items
if ($this->name !== NULL)
{
// Note: substr() is used to chop off the wrapping quotes
$where[] = 'name LIKE "%'.substr(ThumbsUp::db()->quote($this->name), 1, -1).'%"';
}
// Append all query conditions if any
if ( ! empty($where))
{
$sql .= ' WHERE '.implode(' AND ', $where);
}
// We need to order the results
if ($this->orderby)
{
$sql .= ' ORDER BY '.$this->orderby;
}
else
{
// Default order
$sql .= ' ORDER BY name ';
}
// A limit has been set
if ($this->limit)
{
$sql .= ' LIMIT '.(int) $this->limit;
}
// Wrap this in an try/catch block just in case something goes wrong
try
{
// Execute the query
$sth = ThumbsUp::db()->prepare($sql);
$sth->execute(array($this->name));
}
catch (PDOException $e)
{
// Rethrow the exception in debug mode
if (ThumbsUp::config('debug'))
throw $e;
// Otherwise, fail silently and just return an empty item array
return array();
}
// Initialize the items array that will be returned
$items = array();
// Fetch all results
while ($row = $sth->fetch(PDO::FETCH_OBJ))
{
// Return an item_id => item_name array
$items[] = array(
'id' => (int) $row->id,
'name' => $row->name,
'url' => $row->url,
'cat' => $row->cat,
'closed' => (bool) $row->closed,
'date' => (int) $row->date,
'votes_up' => (int) $row->votes_up,
'votes_down' => (int) $row->votes_down,
'votes_pct_up' => (float) $row->votes_pct_up,
'votes_pct_down' => (float) $row->votes_pct_down,
'votes_balance' => (int) $row->votes_balance,
'votes_total' => (int) $row->votes_total,
);
}
return $items;
}
thanks.
You can easily modify "get()" to add the desired functionality:
public function get($cat = null)
{
$where = array();
if ($cat !== null) {
$where[] = 'cat = '. (int) $cat;
}
// ... original code ...
}
Usage:
$items = ThumbsUp::items()->get(1);

Perform function in a while loop

I have this function that returns a bool(true) or bool(false) if the movement exists.
function movement_performed_today($class_id, $client_id){
$class_id = (int)$class_id;
$client_id = (int)$client_id;
$query = mysql_query("SELECT COUNT(`movement`) FROM `completed_movements` WHERE `class_id` = '$class_id' AND `client_id` = '$client_id' AND `date` = CURDATE()");
$movement_performed = mysql_fetch_row($query);
return ($movement_performed[0] > 0);
}
I have this while loop where I want to call this function and if it returns false perform the function completed_movement. I have tried many different ways but I just can't seem to get it to work. Any info will be much appreciated.
if (empty($_POST)=== false){
$i = 0;
while (isset($_POST["first_name"][$i])) {
$movement_data = array(
'user_id' => $session_user_id,
'class_id' => $class_id,
'class_name' => $class_name,
'client_id' => $_POST['client_id'][$i],
'first_name' => $_POST['first_name'][$i],
'last_name' => $_POST['last_name'][$i],
'nickname' => $_POST['nickname'][$i],
'order' => $_POST['order'][$i],
'movement' => $_POST['movement'][$i],
'rep_set_sec' => $_POST['rep_set_sec'][$i],
'rest' => $_POST['rest'][$i],
'date' => $today
);
//assign variable to the function
$isPerformed = movement_performed_today($class_id, $_POST['client_id'][i]);
//if return false perform this function
if(! $isPerformed){ completed_movement($movement_data);}
$i++;
}
} // if empty
What Im trying to do here is each time it loops through check to see if the function movement_performed_today is true or false. If returns false then insert this _POST data in to db. Not sure if Im doing this correctly because even though the function returns true it still calls the completed_movement function and post the info to db.
I believe the issue may lie here. Earlier this would return true or false but now just returns false even though the movement is present. This code:
$movement_performed = mysql_fetch_row($query);
//return ($movement_performed[0] > 0);
var_dump($movement_performed);
Returns this:
array(1) { [0]=> string(1) "0" }
array(1) { [0]=> string(1) "0" }
If the movement is present shouldn't "0" be "1" or higher depending the number of times it matched up with the query.
Here is the working query:
function movement_performed_today($class_id, $client_id, $movement){
$class_id = (int)$class_id;
$client_id = (int)$client_id;
$query = mysql_query("SELECT COUNT(`movement`) FROM `completed_movements` WHERE `class_id` = '$class_id' AND `client_id` = '$client_id' AND `movement` = '$movement' AND `date` = CURDATE()");
$movement_performed = mysql_fetch_row($query);
return ($movement_performed[0] > 0);
}
Here is the working while loop.
if (empty($_POST)=== false){
$i = 0;
while (isset($_POST["first_name"][$i])) {
$movement_data = array(
'user_id' => $session_user_id,
'class_id' => $class_id,
'class_name' => $class_name,
'client_id' => $_POST['client_id'][$i],
'first_name' => $_POST['first_name'][$i],
'last_name' => $_POST['last_name'][$i],
'nickname' => $_POST['nickname'][$i],
'order' => $_POST['order'][$i],
'movement' => $_POST['movement'][$i],
'rep_set_sec' => $_POST['rep_set_sec'][$i],
'rest' => $_POST['rest'][$i],
'date' => $today
);
//check not already performed today
$isPerformed = movement_performed_today($class_id, $_POST['client_id'][$i], $_POST['movement'][$i]);
//if not performed then do insert
if (! $isPerformed){ completed_movement($movement_data);}
$i++;
}
} // if empty
Thanks guys for all your help!
I may be misreading this but it looks like you are setting $return to true or false, not actually returning the value. I believe you want to change:
$return = $movement_performed[0] > 0;
to
if($movement_performed[0] > 0) return true;
else return false;
Edit:
It sounds like you have trouble with your SQL query as well. Try:
$query = mysql_query("SELECT COUNT(`movement`) FROM `completed_movements` WHERE `class_id` = $class_id AND `client_id` = $client_id AND `date` = CURDATE()");
Since columns class_id and client_id appear to be integers, remove the single quotes around their values.
Edit: Corrected syntax, converted SQL result to integer first.
return ((int)$movement_performed[0] > 0 ? true : false);
If you use this return line, the function completed_movement() will return only booleans.
In this case, you want to be strict when doing comparison logic for calling the function.
You'll want to do this:
//if return false perform this function
if ($isPerformed === false) {
completed_movement($movement_data);
}

Categories