Struggling to understand how this particular code works. - php

I am faced with a piece of code that does not make a lot of sense to me. I am working on a website using PHP and Smarty template, but there is one line of code regarding arrays that i do not understand how it works.
$SLang = &SLanguage::getInstance();
$q="SELECT * FROM texte where text_lang='{$SLang->lang}' ORDER BY text_id";
$texte = _sqlFetchQuery($q);
foreach($texte as $text)
{
$texteList[$text['text_alias']]['text'] = $text['text_text'];
if($text["text_category"]==3){
$philosophyList[] = $text["text_text"];
$philosophyListSeo[] = $text["text_alias"];
}
}
The output of "var_dump" on $philosophyList gets out only the "text_text" column from the database, and i do now understand the structure of how it gets there. Can someone care to explain? How does this particular line of code works? $texteList[$text['text_alias']]['text'] = $text['text_text'];

It's called a jagged array.
It's shorthand for this:
$texteList[$text['text_alias']] = array('text'=>$text['text_text']);
So it's creating a named array using whatever text is $text['text_alias'] brings out, and assigning as it's value an array with a named "text" element.
But this is irrelevant to $philosophyList[]. To understand how $philosophyList[] is working, you need to understand how foreach works; basically it takes each item in an array (in this case $texte) and assigns the value of that array item to a variable (in this case $text). This is just an easier way to do a for loop. They could just have easily done:
$philosophyList[] = $texte[$i]["text_text"];

Related

Is there ever a reason to overwrite an array variable with one of its own elements?

I've recently "inherited" a PHP web app that uses a mySQL database as part of its backend. While going through the code, I came across a block that absolutely puzzled me.
$results = array();
$results[] = $mysqli_result->fetch_array();
$results = $results[0];
return $results;
So I get that the first two lines are initializing an empty array and assigning the first row of results from a previous query to that new array. But the third line doesn't make sense to me. As I understand it, fetch_array() only grabs one row at a time; I can't think of any reason to have the $results = $results[0]; line. The best I can come up with is that it's leftover code from when mysql_result was removed.
Is there any reason to have this third line?
No, there is no reason. This is just an example of a "cargo cult code". When you don't know how to do something properly, you just copy/paste some existing code without real understanding whether it is necessary or not.
Of course it makes no sense to create an array, then create a new element in this array, and then reassign this array variable with the first element. Instead, just assign a variable:
$result = $mysqli_result->fetch_array();
Or - better - since this variable is returned right after the assignment, simply return it right away, as the $result variable isn't going to be used anywhere else.
return $mysqli_result->fetch_array();

Overwrite the original array values in PHP in nested loop

Cutting out some of the code on the innermost foreach, I'm trying to change HERE to make it so that it alters the original value. I want to pass a pointer basically and alter it. I was able to kind of do this with the &$ keyword in the foreach but (as the docs state) it results in some buggy behavior and I'm trying to do it the way they, and others on SO suggest. The problem is all the examples I find are for a single foreach, not for nested.
The following code loops properly but when I get to the HERE it doesn't actually alter the original value. Also worth mentioning that $sources could be an array of arrays (by index) or an array of key values. This looping code seems to iterate over both fine though, just not overriding the original value of $sources
fwiw, on top of the &$ I also tried:
$sources[$sourceKey][$rowKey][$cellKey] = $date->format('m/d/Y');
Which $sources[$sourceKey][$rowKey][$cellKey] returns the right value if I print it but it still doesn't overwrite the original array.
function convertDates($sources) {
foreach($sources as $sourceKey => $sourceValue){
foreach ($sourceValue as $rowKey => $rowValue) {
foreach ($rowValue as $cellKey => $cellValue) {
HERE = $date->format('m/d/Y');
}
}
}
}
I never could get this to work correctly since there were two formats this loop could get (JSON encoded object and an array). Making it work for both was much harder than just doing it in JavaScript so instead of modifying on the server I format the data how I want client side and send it up. This formatting is purely presentational and for personal use so if someone were to put in a debugger and change the code to send a different format thats fine and there's no security issues.
So in the end, this code was rewritten in JS and since JS handles arrays and objects using the same pointers the above issue wasn't an issue any longer.

php 7 put data from csv column into a set

I need to read a csv file and put all of the data in a particular column into a Set ( so as to eliminate duplicates ). I have earched through the questions here and I see some similar answers for arrays but I am not well enough versed in php to extrapolate from these examples to my use case.
Specifically, I need to grab a csv file of all the cars towed by the city of Chicago. Then I need to loop through the 'Make' column and grab all of the makes. I do not want to include duplicates so I'm thinking a Set ( which I understand php7 supports) would be an appropriate data structure.
I'm not concerned at all with efficiency at this point, more with simplicity as this is part of a homework assignment. I had the option of just manually going through and picking out the makes but thought that would be an easy out.
I guess array is ok since someone was kind enough to inform me about these two functions.
[code]
$towFileString = file_get_contents("put link here");
file_put_contents('tow-data.csv', $towFileString);
$file = fopen('tow-data.csv', 'rb');
$csvArray = array();
while(!feof($file)){
$csvArray = fgetcsv($file);
}
$allMakes = array_column($csvArray, 'Make');
$uniqueMakes = array_unique($allMakes);
When I run the program, however, PHP tells me this:
Warning: array_column() expects parameter 1 to be array, boolean given
So it is telling me that the array I just created is really a boolean.
I was hoping you could give me some insight into why this is the case
NOTE: I am not asking you to do my work for me. I'd just like a few pointers to get me started in the right direction.
You can put the values of the 'make' column into a seperate array using the array_column function, like this:
$allMakes = array_column($towedCars, 'make');
and then run array_unique on it, which will eliminate all the duplicates:
$uniqueMakes = array_unique($allMakes);

How get size_of $_GET

I want to get the number of values that were submitted via my $_GET. I'm going to be using a for loop and every 7 are going to be saved to a class. Does anyone know how to find the Size_of the $_GET array? I looked through this info $_GET Manual, but don't see what I'm looking for.
This is a code snippet that I started in the class that I go to after the submit.
for($i=0;$i<$_GET<size>;$i++) {
$ID = $_GET["ID"][$i];
$Desc = $_GET["Desc"][$i];
$Yevaluation = $_GET["Yevaluation"][$i];
$Mevaluation = $_GET["Mevaluation"][$i];
$Cevaluation = $_GET["Cevaluation"][$i];
$Kevaluation = $_GET["Kevaluation"][$i];
$comment = $_GET["comment"][$i];
//saving bunch to class next
}
$_GET is an array. Like any other array in PHP, to find the number of elements in an array you can use count() or its alias sizeof().
count($_GET["ID"])
could work. However, then you have to be sure that each index contains the same number of elements.
More secure would be
min(count($_GET["ID"]), count($_GET["Desc"]), ...)
With array_map this can probably be shortcut to something like:
min(array_map(count, $_GET))
Try thinking through the last one, if it seems difficult to you. It's called functional programming and it's an awesome way to shortcut some stuff. In fact array_map calls another function on each element of an array. It's actually the same as:
$filteredGet = array();
foreach ($element in $_GET) { // this is the array_map part
$filteredGet[] = count($element);
}
min($filteredGet);
Even better would be a structure where $i is the first level of the array, but I think this is not possible (built-in) with PHPs $_GET-parsing.

php (complex) dynamic variable name construction

I've got this problem when trying to construct a variable name
(which should output a corresponding array element.)
I start with setting the variables for testing purposes, normally the piece variable would hold the first element of an array $piece.
$wordnumber = 0;
$piece[0] = "forever";
I later echo them right before my problem to see if they're still ok.
echo "$piece[0]";
echo "$wordnumber";
The output is ok.
forever0
But then comes the problem, as I'm trying to make a function that automatically handles every single array element, so I want it to construct the next corresponding variable every time. However somehow it has no value after construction.
$name = ${'piece[' . $wordnumber . ']'};
echo "$name";
outputs nothing...
I've tried a lot of different formatting, I really don't know why I'm failing so hard here.
The code isn't part of any function right now btw.
Update:
$name = $piece[$wordnumber] solves the problem
I'm curious though why my previous formatting didn't work as expected.
Update: Question solved by André, the problem was that $piece[0] wasn't actually part of an array. So $piece was the actual variable. After storing an actual array $piece = array("Redish", "Yellow", "Green"); at start and using global $piece; in my function everything started working like a charm.
I haven’t tested the code, but I think your first approach didn’t work because your variable’s name is “piece”, not “piece[0]”. In other words, ${'piece'}[0] should work, but ${'piece[0]'} is wrong. Try add this in the very beginning of your script and PHP should display you some complaints:
error_reporting(E_ALL);
ini_set("display_errors", 1);
Try just $name = $piece[$wordnumber]; and echo $name
this will output "forever"

Categories