here i have a simple function but this show me data fom sql only in 1 div i want to show [ on div 1 show 1 data, in other div show 2 data, etc etc]...
function load_post($added_by)
{
global $Connection;
$SQL_3 = mysqli_query($Connection, "SELECT * FROM posts WHERE added_by='$added_by'");
$NumPosts = mysqli_num_rows($SQL_3);
$out['num_posts'] = $NumPosts;
while($Fetch_3 = mysqli_fetch_array($SQL_3))
{
$out['id'] = $Fetch_3['id'];
$out['text'] = $Fetch_3['text'];
$out['added_by'] = $Fetch_3['added_by'];
$out['mp4'] = $Fetch_3['mp4'];
$out['likes'] = $Fetch_3['likes'];
$out['youtube'] = $Fetch_3['youtube'];
$out['image'] = $Fetch_3['image'];
$out['date_added'] = $Fetch_3['date_added'];
return $out;
}
}
index.php.
$posts = load_post('gentritabazi');
<div class="settings_forms_content">
<?php echo $posts['text']; ?>
</div>
return finish immediately your function so only one iteration is done. You need to save your results in array and then after loop return that array, sth like this:
$out = array();
while($Fetch_3 = mysqli_fetch_array($SQL_3))
{
$out[] = $Fetch_3;
}
return $out;
and display:
$posts = load_post('gentritabazi');
foreach ($posts as $post) {
echo '<div class="settings_forms_content">';
echo $post['text'];
echo '</div>';
}
Lots to amend, so I commented the code rather than write an essay
function load_post($con, $added_by)
{
// dont use globals, use parameters
//global $Connection;
// select only what you want to see not `*`
$SQL_3 = mysqli_query($con, "SELECT id, text, added_by, mp4,
likes, youtube, image, data_added
FROM posts
WHERE added_by='$added_by'");
// not needed
//$NumPosts = mysqli_num_rows($SQL_3);
//$out['num_posts'] = $NumPosts;
while($Fetch_3 = mysqli_fetch_array($SQL_3))
{
/*
* THsi code would overwrite the last iteration of the while loop
$out['id'] = $Fetch_3['id'];
$out['text'] = $Fetch_3['text'];
$out['added_by'] = $Fetch_3['added_by'];
$out['mp4'] = $Fetch_3['mp4'];
$out['likes'] = $Fetch_3['likes'];
$out['youtube'] = $Fetch_3['youtube'];
$out['image'] = $Fetch_3['image'];
$out['date_added'] = $Fetch_3['date_added'];
*/
// now as you SELECT only what you want yo can simply do
$out[] = $Fetch_3;
//return $out; instantly terminates the function
}
return $out; // return the array
}
Now call your function
// pass the connection as a parameter
$posts = load_post($Connection, 'gentritabazi');
// if you want to know how many results were returned
$result_count = count($posts);
// process the returned array
foreach ( $posts as $post ) {
echo '<div class="settings_forms_content">';
echo $post['text'];
echo '</div>';
}
Your script is at risk of SQL Injection Attack
Have a look at what happened to Little Bobby Tables Even
if you are escaping inputs, its not safe!
Use prepared statement and parameterized statements
$posts = load_post('gentritabazi');
foreach ($posts ['text'] as $postText){
echo "<div class='settings_forms_content'>$postText</div>";
}
first line calls your function which returns the array $posts
this array looks like:
$posts = array(
"id" => array of ids
"text" => array of texts
...
);
if you want to access the third text it would be like this:
$posts ['text'][3]
the foreach iterates to your $post array with index "text" -> which is also an array
every value in this array, $post['text'] will be referenced with $postText -> that means:
$post['text'][1] = $postText (first time looping through foreach-loop)
$post['text'][2] = $postText (secondtime looping through foreach-loop)
..
if you are familiar with loops, a foreach is just the short version for
for(var $i=0;$i<length($posts['text'];$i++){
echo "<div class='settings_forms_content'>$posts['text'][i]</div>";
}
Related
I want to use 'return' function with a while loop for my Mysql query, but it returns only one result.
I have this in my database :
id name author
1 foo fooo
2 foo2 fooo2
It returns only "2", but i want "1","2","3" ect..
Here's my code :
function get_thm_cat() {
require 'database.php';
$req = $bdd->prepare("SELECT * FROM sk_cat ORDER BY id ASC");
$req->execute();
if ($req->rowCount() > 0) {
while ($row = $req->fetch()) {
return '<ul id="ul_cat"><li id="li_cat">'.$row["id"].' Name = '.$row["name"].'<br>';
}
}
$req->closeCursor();
}
With return you stop the execution of the function, which means that when PHP iterates over your loop for the first time and reaches return, it immediately goes back to where you initially called the function. Any subsequent iterations of the while-loop are not executed and your call to $req->closeCursor(); also isn't executed when the result is more than 0 rows because of this.
The easiest way to return multiple strings after each other is to create a temporary variable that you fill up at every iteration and return after the loop, like this:
$output = '';
while ($row = $req->fetch()) {
$output .= '<ul id="ul_cat"><li id="li_cat">'.$row["id"].' Name = '.$row["name"].'<br>';
}
return $output;
return is the command to end the function and continue processing the code where it left off. You should either store the results in the while loop and return the array that holds these results, or you should echo the results in the while loop.
while ($row = $req->fetch_assoc() ) {
echo '<ul id="ul_cat"><li id="li_cat">'.$row["id"].' Name = '.$row["name"].'<br>';
}
or
$results = array();
while ($row = $req->fetch_assoc() ) {
$results[] = '<ul id="ul_cat"><li id="li_cat">'.$row["id"].' Name = '.$row["name"].'<br>';
}
return $results;
Hey guys I have a little issue with a function that retrieves data from a MySQL Database and then I iterate over the results with a foreach loop, checking a value to see if it is null and if it is, replacing it with another value.
The problem with this function is this, that after returning the data I'm only able to view one record retrieved from the database. Probably something simple but it's beyond me.
I would like to do this before passing it to the controller or view. Maybe this isn't possible with the foreach loop? What am I missing?
Here is an example of my code.
public function get_basic_user_data(){
$sql = 'SELECT Account.First_Name, Account.Last_Name, Account.User_Name, Profile_Photos.Thumb_Url
FROM Account
LEFT JOIN Profile_Photos ON Account.idAccount = Profile_Photos.Account_Id
AND Profile_Photos.Active = 1
WHERE Account.idAccount != ?';
$account_id = $this->get_account_id();
$data = $this->db->query($sql, $account_id);
foreach($data->result() as $row){
if($row->Thumb_Url == NULL){
$image = base_url().'assets/images/no_photo_thumb.png';
}else{
$image = $row->Thumb_Url;
}
$new_data = new stdClass;
$new_data->First_Name = $row->First_Name;
$new_data->Last_Name = $row->Last_Name;
$new_data->User_Name = $row->User_Name;
$new_data->Thumb_Url = $image;
}
return $new_data;
}
Hopefully someone can help me with this? Thanks!
At the moment you are just returning the last data row. Change your code like this to return an array of all your rows from that function:
$rows = array()
foreach($data->result() as $row){
if($row->Thumb_Url == NULL){
$image = base_url().'assets/images/no_photo_thumb.png';
}else{
$image = $row->Thumb_Url;
}
$new_data = new stdClass;
$new_data->First_Name = $row->First_Name;
$new_data->Last_Name = $row->Last_Name;
$new_data->User_Name = $row->User_Name;
$new_data->Thumb_Url = $image;
$rows[] = $new_data;
}
return $rows;
This way every row returned from the database will be added to an array named $rows. At the end you have to return your new array.
You are overwriting $new_data each iteration. Try this
$new_data = new stdClass
...
$all_data[] = $new_data;
Instead of checking for null value in the code, you could just use a IFNULL statement in the SQL query, this does separate the logic a bit but it might just be worth it in this case.
The function returns only the last row in the result because the new_data variable is overwritten in every step of your loop. Declare new_data an array at the start of your function and add rows as array elements
...
$new_data[] = new stdClass;
...
Each iteration of the foreach overwrites $new_data so in the end when the function returns, only the last fetched row will be returned. To return more than one row you could store all the rows in an array and then return the array in the end. It would look something like this:
public function get_basic_user_data(){
$sql = 'SELECT Account.First_Name, Account.Last_Name, Account.User_Name, Profile_Photos.Thumb_Url
FROM Account
LEFT JOIN Profile_Photos ON Account.idAccount = Profile_Photos.Account_Id
AND Profile_Photos.Active = 1
WHERE Account.idAccount != ?';
$account_id = $this->get_account_id();
$data = $this->db->query($sql, $account_id);
$data = array();
foreach($data->result() as $row){
if($row->Thumb_Url == NULL){
$image = base_url().'assets/images/no_photo_thumb.png';
}else{
$image = $row->Thumb_Url;
}
$new_data = new stdClass;
$new_data->First_Name = $row->First_Name;
$new_data->Last_Name = $row->Last_Name;
$new_data->User_Name = $row->User_Name;
$new_data->Thumb_Url = $image;
$data[] = $new_data;
}
return $data;
}
To be able to use this function you have to change the code that uses it to loop through the array of objects.
I'm trying to get my head around grabbing all variable I need in Codeigniter and then passing those values to the view.
I understand the concept, but am getting stuck on iterating through an array and adding on another array to each of its keys.
The $data['items'] array contains data passed from a model via the get_all() function. The query is basically "Select * from items".
Each item has multiple features and pictures. In order to get the appropriate values I need the id of an item. I can grab this from the first array ($data['items']) which I can then pass to a model function.
I keep getting various errors when trying to do this via the code below. I've tried defining the features and pictures arrays before the foreach loop - still get errors.
I'm sure my syntax is just wrong. Any help is welcome.
$data['items'] = $this->amazon->get_all();
foreach ($data['items'] as $data )
$id = $data->id;
$data['features'] = $this->amazon->get_features($id);
$data['pictures'] = $this->amazon->get_pictures($id);
}
Edit
Based on feedback I've updated the code to this (lines 24 - 30 of the code):
$items = $this->amazon->get_all();
for($i=0; $i<count($items);$i++) {
$data = $items[$i];
$id = $data->id;
$items[$i]['features'] = $this->amazon->get_features($id);
$items[$i]['pictures'] = $this->amazon->get_pictures($id);
}
PHP is complaining with this:
PHP Fatal error: Cannot use object of type stdClass as array in /var/www/ci/application/controllers/main.php on line 28
Here are the functions from the amazon model:
function get_all()
{
$query = $this->db->get('items');
return $query->result();
}
function get_pictures($id) {
$query = $this->db->query("SELECT link FROM pictures WHERE item_id='$id' AND type IN('thumb_set')");
$style = "border-style:solid; border-width:1px";
$class = "modal-thumb";
$results = '';
foreach ($query->result() as $row) {
$results .= "<li style='$style' class='$class'><img src='$row->link' alt=''/></li>";
}
return $results;
}
function get_features($id) {
$query = $this->db->query("SELECT content FROM features WHERE item_id='$id' ORDER BY feature_num DESC");
$results = '';
foreach ($query->result() as $row) {
$results .= "<li>";
$results .= $row->content;
$results .= "</li>";
}
return $results;
}
I'm thinking i need to use 'results_array()' instead of 'results()'? Are my results returned as an object instead of an array the way things are now?
As you said, you have syntax error in the foreach statement, you are redefining the $data array.
foreach ($data['items'] as $data )
Try this:
$items = $this->amazon->get_all();
for($i=0; $i<count($items);$i++){
$data = $items[$i];
$id = $data->id;
$items[$i]['features'] = $this->amazon->get_features($id);
$items[$i]['pictures'] = $this->amazon->get_pictures($id);
}
I have a php variable with some html content, and some href links. I need to capture this links, save to a DB and replace it with the id of the row that I just saved (is to track how many people follows that link in a newsletter application).
Basicatly I need to do the 2 functions in the example (some_function_to_save_the_links_to_array and some_function_to_save_the_links_to_array).
Thank you a lot for your help!
Example:
$var = "<html><body><h1>This is the newsletter</h1><p>Here I have <a href='http://www.google.com'>Some links</a> in the body of this <a href='http://www.yahoo.com'>Newsletter</a> and I want to extract their.</body></html>";
//Here I just no know how to do this, but I need to save http://www.google.com and http://www.yahoo.com to, maybe, an array, and save this array in a mysql db.
some_function_to_save_the_links_to_array;
while (THERE ARE VALUES IN THE ARRAY OF THE LINKS){
save $array['X'] to db //(I already know how to do it, this is not the problem)
$id = last inserted row in db //I know how to do it also
function_to_replace_the_links_for_the_id;
}
echo $var;
And this is the echo:
<html><body><h1>This is the newsletter</h1><p>Here I have <a href='http://www.mysite.com/link.php?id=1'>Some links</a> in the body of this <a href='http://www.mysite.com/link.php?id=1'>Newsletter</a> and I want to extract their.
<?php
function captureLink($content)
{
$links = array();
$pattern = "/<a\s+href=[\"\']([^>]+?)[\"\']/iU";
if(preg_match_all($pattern,$content,$matches)) {
for($i = 0;$link = $matches[$i][1];$i++)
array_push($links,$link);
}
return $links;
}
function insertLinksToDb(array $links)
{
$linksDb = array();
foreach($links as $link) {
$hash_link = md5($link);
$sql = "SELECT (id) FROM links WHERE hash LIKE :hash";
$sth = $dbh->prepare($sql);
$sth->bindValue(':hash',$hash_link,PDO::PARAM_STR);
$sth->execute();
$result = $sth->fetch(PDO::FETCH_ASSOC);
if(!empty($result)) {
$id = $result['id'];
$linksDb[$id] = $link;
} else {
$sql = " INSERT INTO links (hash,link) VALUES(:hash,:link);";
$sth = $dbh->prepare($sql);
$sth->execute(array(':hash'=>$hash_link,':link',$link));
$linksDb[PDO::lastInsertId] = $link;
}
}
return $linksDb;
}
function normallizeLinks($content,array $links)
{
foreach($links as $id => $link) {
//str_replace working faster than strtr
$content = str_replace($link,'/links.php?id='.$id,$content);
}
return $content;
}
I am in the process of making a quick PHP based forum, and each post in a forum will appear under its "parent" post, but slightly more indented.
To get all the posts in that order, I have the following function:
private function getData($pid, $offset)
{
$sql = 'SELECT id, subject, date
FROM post
WHERE forum_id = ? AND parent_id = ?';
$sth = $this->db->prepare($sql);
$sth->bind_param("ii", $this->id, $pid);
$sth->bind_result($id, $subject, $date);
$sth->execute();
$data = array();
while ( $sth->fetch() )
{
$row['id'] = $id;
$row['subject'] = $subject;
$row['date'] = $date;
$row['offset'] = $offset;
//Add this 'parent' post to the data array
$data[] = $row;
//Before moving on to next post, get all its children
$data[] = $this->getData($id, $offset+1);
}
$sth->close();
return $data;
}
This isn't working because I am executing another query before closing and fetching all the data from my current statement handler.
Is there a way to maybe separate the queries so they don't conflict with each other? Or any other way to by-pass this? Or will I simply have to restructure how I get my data?
Fetch all the rows into an array, then loop over them.
$rows = array();
while ( $sth->fetch() ) {
$row['id'] = $id;
$row['subject'] = $subject;
$row['date'] = $date;
$row['offset'] = $offset;
// the cool way is $rows[] = compact('id', 'subject', 'date', 'offset');
$rows[] = $row;
}
$sth->close();
foreach ($rows as $row) {
//Add this 'parent' post to the data array
$data[] = $row;
//Before moving on to next post, get all its children
$data[] = $this->getData($id, $row['offset'] + 1);
}
I will give you a example to show how to do this, this is the table i will use for the example (after just add the forum_id):
CREATE TABLE msgs (
id INT NOT NULL AUTO_INCREMENT,
date DATETIME,
name VARCHAR(100),
message TEXT,
parent_id INT NOT NULL DEFAULT 0
);
Then, with one query do:
$query = mysql_query("SELECT * FROM msgs ORDER BY id");
Some arrays to build the "posts tree", all parent_id = 0 will be root posts:
$all_messages = array(); // Will store all messages
$root_messages = array(); // Will store only the root (or more than one if you allow)
while($row=mysql_fetch_assoc($query)){ // Main loop
$all_messages[$row['id']] = array(
'inner_messages'=>array(),
'date'=> $row['date'],
'name'=> $row['name'],
'message'=>$row['message'],
'id'=>$row['id']
);
if($row['parent_id']=='0'){ // If is a root post
$root_messages[] = &$all_messages[$row['id']];
}else{ // If not a root post, places within parent message
$all_messages[$row['parent_id']]['inner_messages'][] = &$all_messages[$row['id']];
}
}
Now to print, use a recursion:
function writeTree($msgs){
foreach($msgs as $m){
echo '<div>';
echo '<h2>'.$m['name'].' ('.$m['date'].')</h2>';
echo '<div class="text">'.$m['message'].'</div>';
writeTree($m['inner_messages']);
echo '</div>';
}
}
writeTree($root_messages);