PHP Array only stores last value - php

Well, basically what this code does is grab some links from a source code of a website and send them to an mp3 player.
The big problem is on the get_link function, where i want to store the urls to an array. The section where im having problems is commented.
Sorry for posting all this code but the functions are connected to each others.
function getHost($db,$id){
if(isset($_GET['id'])){
$sql1 = "SELECT host FROM mixtape WHERE id=?";
$stm = $db->prepare($sql1);
$stm->execute(array($id));
$row1 = $stm->fetch(PDO::FETCH_ASSOC);
if($row1['host']=='host1'){
$sql2 = "SELECT link1 FROM faixa WHERE id_mixtape IN(SELECT id FROM mixtape WHERE id=?)";
$stm = $db->prepare($sql2);
$stm->execute(array($id));
$rows_affected = $stm->rowCount();
$array=array();
if (count($rows_affected) > 0) {
for($i=1; $i <= $rows_affected; $i++) {
$row2 = $stm->fetch(PDO::FETCH_ASSOC);
$url=$row2['link1'];
get_Link($db,$url,$i,$rows_affected,$array);
}
}
}
}
}
function get_Link($db,$url,$pos,$rows_affect,$array){
$find = 'url:';
$reg_exUrl = "/(http|https|ftp|ftps)\:\/\/[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,3}(\/\S*)?/";
$data = file_get_contents($url);
$data = explode("\n", $data);
for ($line = 0; $line < count($data); $line++) {
if (strpos($data[$line], $find) !== false) {
$link = preg_replace($reg_exUrl,"", $data[$line]);
$v[]=$link;
}
}
if($pos!=$rows_affect-1){
$url="mylink.com/".$link."|";
}else{
$url="mylink.com/".$link."&amp";
}
$array[$pos]=$url;
var_dump($array); // Here says that are 3 values in the array. True
if($pos==$rows_affect-1){
var_dump($array); // Here is only showing the last value in the array. Why?
player($db,$array);
}
}
function player($db,$array){
if(isset($_GET['id'])){
foreach($array as $i=>$item){
echo $item;
}
}
}

This piece of code:
$c=0;
for ($line = 0; $line < count($data); $line++) {
if (strpos($data[$line], $find) !== false) {
$link = preg_replace($reg_exUrl,"", $data[$line]);
$v[$c]=$link;
}
}
Should be like:
$c=0;
for ($line = 0; $line < count($data); $line++) {
if (strpos($data[$line], $find) !== false) {
$link = preg_replace($reg_exUrl,"", $data[$line]);
$v[$c]=$link;
$c = $c+1; //this is missing or $c++;
}
}
OR:
for ($line = 0; $line < count($data); $line++) {
if (strpos($data[$line], $find) !== false) {
$link = preg_replace($reg_exUrl,"", $data[$line]);
$v[]=$link; //That way works too
}
}

Miguelfsf, you must first learn about variable scope.
Your problem is, you created the $array=array() (the $array show be the $row2).
You declared a new variable, but you didn't used, the $array was just to tell you, declare your array that way
$row2=array().
After that you need to do
$row2[] = $stm->fetch(PDO::FETCH_ASSOC);
Why?
Because the assoc returns a associative array, then it will do
$array => {title => "last title} = $newData => {title => "new title"}
It will replace the value
Using the [] everytime you do this it'll create a new element.
Then
{
0 => { title => "title1"}
1 => { title => "title2"}
2 => { title => "title3"}
3 => { title => "title4"}
}

Related

php foreach loop giving only 1 result from the array

I have a csv file containing attributes of the stores (id, name, category, featured, etc) to be displayed in a project. For now I need to display an array of featured stores with the condition 'featured'='TRUE'. There are 10 results.
Here's the code to read the file and save the data as an associative array
function read_all_stores() {
$file_name = 'csv_files/stores.csv';
$fp = fopen($file_name, 'r');
$first = fgetcsv($fp); // get the first row aka headlines of the file
$stores = [];
while ($row = fgetcsv($fp)) {
$i = 0;
$store = [];
foreach ($first as $col_name) {
$store[$col_name] = $row[$i];
$i++;
}
$stores[] = $store;
}
return $stores;
}
sample result of the first 5 stores
Now I want to display only the stores that has attribute featured = 'TRUE'. I tried this code:
function get_store() {
$stores = read_all_stores();
$feature = [];
foreach ($stores as $s) {
while ($s['featured'] == 'TRUE') {
$feature[] = $s;
return $feature;
}
}
return false;
}
But it only returns one result.
I tried removing the single quotation mark but it seems to only accept the 'TRUE' value as string instead of boolean. How can I fix this foreach loop??
Your problem is that as soon as you find a matching result: $s['featured'] == 'TRUE', you return it: return $feature;. Instead, you need to process all values in $stores before returning your result. If there are matching stores (count($feature) is non-zero i.e. truthy), return them, otherwise return false.
function get_store() {
$stores = read_all_stores();
$feature = [];
foreach ($stores as $s) {
if ($s['featured'] == 'TRUE') {
$feature[] = $s;
}
}
return count($feature) ? $feature : false;
}
Two problems in your code:
In get_store() method you are returning as soon as you find a match. Instead you should add all the matched ones and then return at the end.
For checking a match you should use if instead of while
Here is the modified version of your code:
<?php
function read_all_stores() {
$file_name = 'stores.csv';
$fp = fopen($file_name, 'r');
$first = fgetcsv($fp); // get the first row aka headlines of the file
$stores = [];
while ($row = fgetcsv($fp)) {
$i = 0;
$store = [];
foreach ($first as $col_name) {
$store[$col_name] = $row[$i];
$i++;
}
$stores[] = $store;
}
return $stores;
}
function get_store() {
$stores = read_all_stores();
$feature = [];
foreach ($stores as $s) {
if ($s['featured'] == 'TRUE') {
$feature[] = $s;
}
}
return $feature;
}
echo count(get_store());

Retrieving data from CSV in PHP

I have a CSV file containing two rows of data, one which the user will input and the other will be returned. e.g. inputting a post/zipcode which will be found in the CSV file, the data in the next cell should be returned.
<?php
function csv_to_array($filename='bn.csv', $delimiter=',')
{
if(!file_exists($filename) || !is_readable($filename))
return FALSE;
$header = NULL;
$data = array();
if (($handle = fopen($filename, 'r')) !== FALSE)
{
while (($row = fgetcsv($handle, 1000, $delimiter)) !== FALSE)
{
if(!$header)
$header = $row;
else
$data[] = array_combine($header, $row);
}
fclose($handle);
}
return $data;
}
function search($data, $x) {
for($i = 0; $i < sizeof($data); $i++) {
if($data[$i] == $x) return $i;
}
return -1;
}
$data = array("bn.csv");
echo search($data, "BN1 1AA");
print_r(csv_to_array('bn.csv'));
?>
Currently I am just getting -1 returned, what should I do?
Thanks in advance.
$data = array("bn.csv"); creates an array with the literal string bv.csv in it. I'm guessing you want $data = csv_to_array("bn.csv"); here instead. I would build an associative array like this:
$data = [
'BN1 1AA' => 'E05002432',
'...' => '...',
'...' => '...',
];
Via something like:
while (($row = fgetcsv($handle, 1000, $delimiter)) !== FALSE) {
$data[$row[0]] = $row[1];
}
Thus, you can refer to an entry directly by its key, you don't need to iterate over every item to search for a match:
$search = 'BN1 1AA';
if (array_key_exists($search, $data)) {
echo $data[$search];
} else {
echo "not found";
}
There are several problems towards the end of your code.
In search() - you are trying to match the postcode with the entire row in $data[$i] == $x, $data[$i] is actually a list of the fields in the row, so perhaps matching it with ($data[$i][$field] == $x) and $field is the field name of the postcode.
You were calling search() with an array of the file names for the data and not the data from the file, so this code calls csv_to_array() first and passes the result to search()...
Lastly - the sample data didn't have BN1 1AA in it anyway, so should return -1.
function search($data, $x, $field = 'Postcode') {
for($i = 0; $i < sizeof($data); $i++) {
if ($data[$i][$field] == $x)
return $i;
}
return -1;
}
$data = csv_to_array('a.csv');
print_r($data);
echo search($data, "BN1 1AD");

php how to get whole line after spicific character from text file?

I have text file
name,name1
willhaveishere1
name,name2
willhaveishere2
name,name3
willhaveishere3
i want read it and return like that
$nn = name1
$ss = willhaveishere1
with my code i get only name1
my code is
$file1 = "file.txt";
$file = file($file1);
$count = count($file);
if($count > 0) {
$i = 1;
foreach($file as $row) {
$n = strstr($row, 'name,');
$cc = array("name,");
$dd = array("");
$nn = str_replace($cc, $dd, $n);
echo $nn;
$i++; } }
This is probably what you need
if($count > 0) {
foreach($file as $row) {
$pos = strpos($row, ',');
if($pos !== false){
echo substr($row, $pos + 1);
$nn[] = substr($row, $pos + 1);
} else {
echo $row;
$ss[] = $row;
}
}
}
EDIT
Yes, just loop through, but make sure both $nn and $ss has same count, which is depending on your file.
Also Note: mysql_* functions has been deprecated, so please use mysqli or PDO instead
$count = count($nn);
for($i=0; $i < $count; $i++){
$sql = "INSERT INTO users(name, line) VALUES('$nn[$i]', '$ss[$i]')"; mysql_query($sql);
}
EDIT 2
try this example:
$file = array(
0 => 'name,name1',
1 => 'willhaveishere1',
2 => 'name,name2',
3 => 'willhaveishere2',
4 => 'name,name3',
5 => 'willhaveishere3'
);
$count = count($file);
if($count > 0) {
foreach($file as $row) {
$pos = strpos($row, ',');
if($pos !== false){
$nn[] = substr($row, $pos + 1);
} else {
$ss[] = $row;
}
}
}
echo '<pre>';
$count = count($nn);
for($i=0; $i < $count; $i++){
$sql = "INSERT INTO users(name, line) VALUES('$nn[$i]', '$ss[$i]');";
echo $sql.PHP_EOL;
}
You can try this straightforward method:
if($fh = fopen("file.txt","r")){
$nameBefore = false;
//loop through every line of your file
while (!feof($fh)){
$line = fgets($fh);
//check if the name was detected in previous line
if ($nameBefore !== false)
{
//you have the set of name and line, do what you want
echo $nameBefore . ': ' . $line . '<br />';
$nameBefore = false;
}
else
{
//see if the line is made of two coma separated segments and the first one is 'name'
//Remember the name for the next line
$parts = explode(',', $line);
if (count($parts) == 2 && $parts[0] == 'name')
$nameBefore = $parts[1];
}
}
fclose($fh);
}
One option is to use strpos to find the first occurrence of the character in the line, and if found remove everything from the line before that position. This way you are left with only the part of the line you are interested in.
Code:
$character = ',';
$fileHandle = fopen('file.txt', 'r');
while (!feof($fileHandle)) {
// Retrieve the line from the file
$line = fgets($fileHandle);
// If the line contains the character
// Remove everything before the character
$charPos = strpos($line, $character);
if ($charPos !== false) {
$line = substr($line, $charPos + 1);
}
// Do something with the remainder of the line
echo $line . PHP_EOL;
}
fclose($fileHandle);
Output:
name1
willhaveishere1
name2
willhaveishere2
name3
willhaveishere3
If you wish to retrieve the following line, simply do another retrieve line call in your loop:
while (!feof($fileHandle)) {
// Retrieve two lines in one loop iteration
$lineOne = fgets($fileHandle);
$lineTwo = fgets($fileHandle);
}
Making sure to only apply the comma replace part on the first line. This can lead to problems though if your data is... inconsistent.
Hope this helps.

PHP: Undefined offset in stripos

Hello! Im working with AJAX with DB and when trying to render my db in an option and select tag it gives me an "Undefined offset error".
Here is my code:
$sql = "SELECT word FROM words";
$result = mysql_query($sql);
$response = "";
$size = 0;
if($result === FALSE) {
die(mysql_error());
}
while ($row = mysql_fetch_array($result)) {
for($i = 0; $i < count($row); $i ++) {
$pos = stripos(strtolower($row[$i]), $pattern); //Here marks the error
if(!($pos === false)) {
$size ++;
$word = $row[$i];
$response .= "<option value=\"$word\">$word</option>";
}
}
}
if($size > 0) {
echo "<select id=\"list\" size=$size onclick=\"selectValue()\">$response</select>";
}
The idea of this app is you can start typing any word and it will search for words that matches with the input, displaying it first in an option HTML tag and when no more options are matched it's displayed in a select HTML tag.
It's kind of working but it displays this errors. Can someone help me? Thanks!!
Here is modified script:
while ($row = mysql_fetch_assoc($result)) {
$pos = stripos(strtolower($row['word']), $pattern);
if(!($pos === false)) {
$size ++;
$word = $row['word'];
$response .= "<option value=\"$word\">$word</option>";
}
}
But actually next script will run faster:
if ($result = mysql_query("SELECT word FROM words where word like '%".mysql_real_escape_string($pattern)."%'")) {
$response = "";
$size = 0;
while ($row = mysql_fetch_assoc($result)) {
$size ++;
$word = htmlspecialchars($row['word']);
$response .= "<option value=\"$word\">$word</option>";
}
echo "<select id=\"list\" size=$size onclick=\"selectValue()\">$response</select>";
}
And yes - use mysqli instead of mysql, mysql_ functions are deprecated.

PHP - CSV to table not converting as expected

I am trying to create SQL INSERT statements from a CSV file. I have successfully opened and read the file. I have even output the file in a table format. However, the alterations I do in the for loop such as when $c == 0 do not work. It just outputs to the table exactly as it was in the csv file. That is what I am trying to change! To keep with that example, I am trying to make the name "John Doe" be "john" and "Doe". The CSV file has the names as one and I'd like to split into first and last.
Also, the phone numbers aren't changing either. The code to change them begins with $c == 5. The funny thing is when I put them into here: http://ideone.com/HfGXJk It works fine.
<?php
fgetcsv_PHP();
function fgetcsv_PHP()
{
if (($handle = fopen("guests.csv", "r")) !== FALSE)
{
$length = 1000;
$delimiter = ",";
$fname = array();
$lname = array();
$address = array();
$city = array();
$state = array();
$zip = array();
$phone = array();
$email = array();
//print opening table
echo "<table border='1'>\n";
while ( ( $data = fgetcsv( $handle, $length, $delimiter ) ) !== FALSE )
{
// Count number of array elements in $data
$num = count($data);
// Print opening table row HTML tag
echo "<tr>\n";
//loop through array
for ($c=0; $c < $num; $c++)
{
if ($c == 0)
{
$name = $c;
$name = explode(" ",$name);
$first = array_shift($name);
$last = array_pop($name);
array_push($fname, $first);
array_push($lname, $last);
echo "<td>".$data[$first]."</td>\n";
}
if ($c == 1)
{
array_push($address, $c);
echo "<td>".$data[$c]."</td>\n";
}
if ($c == 2)
{
array_push($city, $c);
echo "<td>".$data[$c]."</td>\n";
}
if ($c == 3)
{
array_push($state, $c);
echo "<td>".$data[$c]."</td>\n";
}
if ($c == 4)
{
array_push($zip, $c);
echo "<td>".$data[$c]."</td>\n";
}
if ($c ==5)
{
$phnum = $c;
$phnum = preg_replace('~[^0-9]~','',$phnum);
array_push($phone, $phnum);
echo "<td>".$data[$phnum]."</td>\n";
}
if ($c == 6)
{
array_push($email, $c);
echo "<td>".$data[$c]."</td>\n";
}
}
// Print closing table row HTML tag
echo "</tr>\n";
}
// Print close table HTML tag
echo "</table>";
// Close the file pointed to by $handle
fclose($handle);
}
}
?>
The part reading the name, sets $name to 0, explodes it at the non existing space, puts the 0 from the first element of the array (from the explode) in $first and outputs $data[$first] meaning $data[0] - the original value.
Refactored to PHP 5.5:
$file = new SplFileObject('guests.csv', 'r');
$file->setFlags(SplFileObject::READ_CSV);
$file->setCsvControl(',', '"');
$converter = function($traversable) {
foreach ($traversable as $data) {
list($first, $last) = explode(' ', $data[0]);
$address = $data[1];
$city = $data[2];
$state = $data[3];
$zip = $data[4];
$phone = preg_replace('([^\d])', '', $data[5]);
$email = $data[6];
$result = array(
'first' => $first,
'last' => $last,
'address' => $address,
'city' => $city,
'state' => $state,
'zip' => $zip,
'phone' => $phone,
'email' => $email,
);
yield $result;
}
};
foreach ($converter($file) as $data) {
var_dump($data);
}
The code you posted to the other site is not the code you posted here. If that works, fine. It has little to do with this:
if ($c ==5)
{
$phnum = $c;
$phnum = preg_replace('~[^0-9]~','',$phnum);
array_push($phone, $phnum);
echo "<td>".$data[$phnum]."</td>\n";
}
Look at $phnum. The first thing you do is set it to $c, i.e 5. Then you remove all the non-numeric characters in 5, push the result onto an array which you don't appear to use, and output $data[$phnum], i.e. $data[5], your original data.

Categories