The code below has two commented-out variations on one line. They produce rather different results, as you'll see if run them - without the space between $array and [$key], the individual letters of the key are mapped out to the array values.
Can someone explain what's happening here and why?
Thanks!
<?php
$letters = array('A','B','C');
$numbers = array(1,2,3);
$matrix = array('Letter' => $letters, 'Number' => $numbers);
foreach($matrix as $array => $list)
{
echo '<ul>';
foreach($list as $key => $value)
// {echo "<li>$array [$key] = $value ";}
// {echo "<li>$array[$key] = $value ";}
echo '</ul>';
}
"$array[$key]" is interpreted as the array access (value of $array[$key]). Same as echo $array[$key];.
"$array [$key]" is interpreted as two different variables: $array and $key. Same as echo $array." [".$key."]";.
The reason for the difference in output is due to the way that PHP parses strings containing variables.
If you change:
{echo "<li>$array [$key] = $value ";}
to
{echo "<li>" . $array [$key] . " = $value ";}
It will result in the same thing and the line below it.
{echo "<li>$array[$key] = $value ";}
PHP is mostly whitespace agnostic, but not inside of strings where intrinsically whitespace matters.
remember that "double quotes" tries to execute your code, while "single quotes" deals your code as text only.
in this case:
echo "<li>$array[$key] = $value ";
this code is being evaluated. here is saying something like "put this value in this position of this array". in the other hand, this:
echo "<li>$array [$key] = $value ";
isn't being evaluated because, to php, doens't make sense to it's parser assign a value to something like this:
[$someting] = $value;
the above code returns a fatal error.
your code doesn't return a fatal error because php tries to handle your code in some way that doesn't throw an exception.
the last example of your code (the one with spaces) is the same as this:
echo '<li>' . $array . '[' . $key . '] = ' . $value;
in short: want to show some variable in some string? put the variables off the php string's interpretation:
echo $myvar . ' = ' . $myvalue;
Related
I was asked to create simulation array_keys function, but check equality "==" returns false.
But with "strcmp ($a, $b) == 0" return true.
class Utility
{
public function convertArrayKeys(array $array)
{
$i = 0;
$elements = [];
foreach ($array as $element=>$value) {
$elements[] = ' ' . $i++ . " => '" . $element . "'";
}
return 'array ( ' . implode(', ', $elements) . ', )';
}
public function testStrings(array $array)
{
$arrayOur = $this->convertArrayKeys($array);
$arrayPhp = var_export(array_keys($array),true);
if ($arrayOur == $arrayPhp){
echo 'They are identical :)';
} else {
echo 'They are not identical :(';
echo '<br>';
print_r(str_split($arrayOur));
echo '<br>';
print_r(str_split($arrayPhp));
}
}
}
View:
$repository = array('box'=>'blue', 'cube'=>'red', 'ball'=>'green');
$utility = new Utility();
echo "OUr array_keys: ";
echo $utility->convertArrayKeys($repository);
echo "<br />";
echo "PHP array_keys: ";
print_r (var_export(array_keys($repository)));
echo "<hr >";
echo "<br />";
echo $utility->testStrings($repository);
I would appreciate to know because
Edit: The reason that the two don't work in THIS instance is that your functions dont produce identical outputs: yours produces:
array ( 0 => 'box', 1 => 'cube', 2 => 'ball', )
where the php function produces:
array (
0 => 'box',
1 => 'cube',
2 => 'ball',
)
If you were to view that in the web browser i think the web browser renderer does whitespace trickery. However try putting uhh <pre> tags around it (or run in command line to check).
Basically == does more then compare the two values - the documentation suggests "after type juggling". You can get some weird things by comparing strings using ==. One good example is: '1e3' == '1000'. It is useful to use ==at times, but possibly not in conjunction with strings.
Strcmp also though doesn't return a true/false answer, but a -1, 0, 1 answer indicating which string is alphabetically in front of the other.
You should also look at === which can also have helpful uses, but personally I would stick with strcmp with strings.
Hi never use == in PHP. It will not do what you expect. Even if you are comparing strings to strings, PHP will implicitly cast them to floats and do a numerical comparison if they appear numerical.
try these you will know the reason
$something = 0;
echo ('password' == $something) ? 'true' : 'false';// true
$something = 0;
echo ('password' === $something) ? 'true' : 'false'; // false
echo strcmp('password123',$something); // 1
Because they are not arrays, rather they are strings. Arrays are not created like this. you are doing it wrong. Were they arrays then
if ($arrayOur == $arrayPhp)
would have evaluated to true. But they are just strings and
"strcmp ($a, $b) == 0"
Does not return true, because there are whitespaces in the first string,
return 'array ( ' . implode(', ', $elements) . ', )';
You are doing it completely wrong. You need to correct your approach.
I'm working on a php function that will compare the components of two arrays. Each value in the arrays are only one english word long. No spaces. No characters.
Array #1: a list of the most commonly used words in the english
language. $common_words_array
Array #2: a user-generated sentence, converted to lowercase, stripped
of punctuation, and exploded() using the space (" ") as a delimiter.
$study_array
There's also a $com_study array, which is used in this case to keep
track of the order of commonly used words which get replaced in the
$study_array by a "_" character.
Using nested for loops, what SHOULD happen is that the script should compare each value in Array #2 to each value in Array #1. When it finds a match (aka. a commonly used english word), it will do some other magic that's irrelevant to the current problem.
As of right now, PHP doesn't recognize when two array string values are equivalent. I'm adding in the code to the problematic function here for reference. I've added in a lot of unnecessary echo commands in order to localize the problem to the if statement.
Can anybody see something that I've missed? The same algorithm worked perfectly in Python.
function create_question($study_array, $com_study, $common_words_array)
{
for ($study=0; $study<count($study_array); $study++)
{
echo count($study_array)." total in study_array<br>";
echo "study is ".$study."<br>";
for ($common=0; $common<count($common_words_array); $common++)
{
echo count($common_words_array)." total in common_words_array<br>";
echo "common is ".$common."<br>";
echo "-----<br>";
echo $study_array[$study]." is the study list word<br>";
echo $common_words_array[$common]." is the common word<br>";
echo "-----<br>";
// The issue happens right here.
if ($study_array[$study] == $common_words_array[$common])
{
array_push($com_study, $study_array[$study]);
$study_array[$study] = "_";
print_r($com_study);
print_r($study_array);
}
}
}
$create_question_return_array = array();
$create_question_return_array[0] = $study_array;
$create_question_return_array[1] = $com_study;
return $create_question_return_array;
}
EDIT: At the suggestion of you amazing coders, I've updated the if statement to be much more simple for purposes of debugging. See below. Still having the same issue of not activating the if statement.
if (strcmp($study_array[$study],$common_words_array[$common])==0)
{
echo "match found";
//array_push($com_study, $study_array[$study]);
//$study_array[$study] = "_";
//print_r($com_study);
//print_r($study_array);
}
EDIT: At bansi's request, here's the main interface snippet where I'm calling the function.
$testarray = array();
$string = "This is a string";
$testarray = create_study_string_array($string);
$testarray = create_question($testarray, $matching, $common_words_array);
As for the result, I'm just getting a blank screen. I would expect to have the simplified echo statement output "match found" to the screen, but that's not happening.
(EDIT) make sure your that your splitting function removes excess whitespace (e.g. preg_split("\\s+", $input)) and that the input is normalized properly (lowercase'd, special chars stripped out, etc.).
On mobile and can't seem to copy text. You forgot a dollar sign when accessing the study array in your push command.
change
array_push($com_study, $study_array[study]);
to
array_push($com_study, $study_array[$study]);
// You missed a $ ^ here
Edit:
The following code outputs 3 'match found'. i don't know the values of $common_words_array and $matching, so i used some arbitrary values, also instead of using function create_study_string_array i just used explode. still confused, can't figure out what exactly you are trying to achieve.
<?php
$testarray = array ();
$string = "this is a string";
$testarray = explode ( ' ', $string );
$common_words_array = array (
'is',
'a',
'this'
);
$matching = array (
'a',
'and',
'this'
);
$testarray = create_question ( $testarray, $matching, $common_words_array );
function create_question($study_array, $com_study, $common_words_array) {
echo count ( $study_array ) . " total in study_array<br>";
echo count ( $common_words_array ) . " total in common_words_array<br>";
for($study = 0; $study < count ( $study_array ); $study ++) {
// echo "study is " . $study . "<br>";
for($common = 0; $common < count ( $common_words_array ); $common ++) {
// The issue happens right here.
if (strcmp ( $study_array [$study], $common_words_array [$common] ) == 0) {
echo "match found";
}
}
}
$create_question_return_array = array ();
$create_question_return_array [0] = $study_array;
$create_question_return_array [1] = $com_study;
return $create_question_return_array;
}
?>
Output:
4 total in study_array
3 total in common_words_array
match foundmatch foundmatch found
Use === instead of ==
if ($study_array[$study] === $common_words_array[$common])
OR even better use strcmp
if (strcmp($study_array[$study],$common_words_array[$common])==0)
Use built-in functions wherever possible to avoid unnecessary code and typos. Also, providing sample inputs would be helpful too.
$study_array = array("a", "cat", "sat", "on","the","mat");
$common_words_array = array('the','a');
$matching_words = array();
foreach($study_array as $study_word_index=>$study_word){
if(in_array($study_word, $common_words_array)){
$matching_words[] = $study_word;
$study_array[$study_word_index] = "_";
//do something with matching words
}
}
print_r($study_array);
print_r($matching_words);
Edit: The aim of my method is to delete a value from a string in a database.
I cant seem to find the answer for this one anywhere. Can you concatenate inside a str_replace like this:
str_replace($pid . ",","",$boom);
$pid is a page id, eg 40
$boom is an exploded array
If i have a string: 40,56,12 i want to make it 56,12 however without the concatenator in it will produce:
,56,12
When I have the concat in the str_replace it doesnt do a thing. Is this possible?
Answering your question: yes you can. That code works as you would expect it to.
But this approach is wrong. It will not work for $pid = 12; (last element, without trailing coma) and will incorrectly replace 40, in $boom = '140,20,12';
You should keep it in array, search for unwanted value, if found unset it from the array and then implode with coma.
$boom = array_filter($boom);
$key = array_search($pid, $boom);
if($key !== false){
unset($boom[$key]);
}
$boom = implode(',',$boom);
[+] Your code does not work because $boom is an array, and str_replace operates on string.
As $boom is an array, you don't need to use array on your case.
Change this
$boom = explode(",",$ticket_array);
$boom = str_replace($pid . ",","",$boom);
$together = implode(",",$boom);
to
$together = str_replace($pid . ",","",$ticket_array);
Update: If you want still want to use array
$boom = explode(",",$ticket_array);
unset($boom[array_search($pid, $boom)]);
$together = implode(",",$boom);
After you have edited it becomes clear that you want to remove the value of $pid from the array $boom which contains one number as a value. You can use array_search to find if it is in at if in with which key. You can then unset the element from $boom:
$pid = '40';
$boom = explode(',', '40,56,12');
$r = array_search($pid, $boom, FALSE);
if ($r !== FALSE) {
unset($boom[$r]);
}
Old question:
Can you concatenate inside a str_replace like this: ... ?
Yes you can, see the example:
$pid = '40';
$boom = array('40,56,12');
print_r(str_replace($pid . ",", "", $boom));
Result:
Array
(
[0] => 56,12
)
Which is pretty much like you did so you might be looking for the problem at the wrong place. You can use any string expression for the parameter.
It might be easier for you if you're unsure to create a variable first:
$pid = '40';
$boom = array('40,56,12');
$search = sprintf("%d,", $pid);
print_r(str_replace($search, "", $boom));
You should store your "ticket array" in a separate table.
And use regular SQL queries (UPDATE, DELETE) to manipulate it.
A relational word in the name of your database is for the reason. And you are abusing this smart software with such a barbaric approach.
You could use str_split, it converts a string to an array, then with a foreach loop echo all the values except the first one.
$numbers_string="40,56,12";
$numbers_array = str_split($numbers_string);
//then, when you have the array of numbers, you could echo every number except the first separating them with a comma
foreach ($numbers_array as $key => $value) {
if ($key > 0) {
echo $value . ", ";
}
}
If you want is to skip a value not by it's position in the array, but for it's value then you could do this instead:
$unwanted_value="40";
foreach ($numbers_array as $key => $value) {
if ($value != $unwanted_value) {
echo $value . ", ";
}
else {
unset($numbers_array[$key]);
$numbers_array = array_values($numbers_array);
var_dump($numbers_array);
}
}
I am doing my head in trying to do a simple retrieval for specific arrays within a script so I have an original associative array:
$vNArray ['Brandon'] = $item[3];
$vNArray['Smith']= $item[4];
$vNArray ['Johnson']= $item[5];
$vNArray ['Murphy']= $item[6];
$vNArray ['Lepsky']= $item[7];
Which outputs a common result for most values:
foreach ($vNArray as $key => $value){
if(!empty($value)){
$result .= "\t\t\t\t<li><strong>$key</strong>" .$value. "</li>\n";
}
But then I want two of these arrays to render differently so I added another script suggested by someone:
$display_id=array('Brandon', 'Murphy');
foreach ($vNArray as $key => $value){
if(!empty($value)){
//Looks into the display_id array and renders it differently
if (in_array($key, $display_id)) {
$result .= "\t\t\t\t<li id=\"$key\"><strong>$key</strong>$value</li>\n";
} else {
$result .= "\t\t\t\t<li><strong>$key</strong>$value</li>\n";
}
}
}
The problem is that i want the result for these arrays to contain both within the first result but when I tried to output
$result .= "\t\t\t\t$key[1]".$value[1]." \n";
PHP thinks that the index is the value's character index, so I'm having major syntax issues like id="/" r.
I have also tried
$result .= "\t\t\t\t<li id=\"". $display_id['Brandon']$value.\""><strong>$key[1]</strong>". $display_id['Murphy']$value." </li>\n";
But I am still getting wrong syntax issues...like
syntax error, unexpected T_VARIABLE
Or some other error like this.
Could someone please help?
EDITED
I have made the syntax corrections but I still need to specify the index:
The result from
result .= "\t\t\t\t<li id=\"". $display_id['Brandon'] . $value."\"><strong>" . $key[1] . "</strong>". $display_id['Murphy'] . $value." </li>\n";
Needs to be (Note how each value is on the same output depending on what I'm targeting):
<li id="Brandon Value"><strong>Brandon</strong> Murphy Value</li>
Right now it ignores the index value of . $display_id['Brandon'] . $value. or . $display_id['Murphy'] . $value." all together and just repeats:
<li id="Brandon Value"><strong>Brandon</strong> Brandon Value</li>
<li id="Murphy Value"><strong>Murphy</strong> Murphy Value</li>
Just do $key, forget the [1] bit. Same with $value.
Each value needs to be concatenated with another, so for example:
echo $a . $b . $c . $d . $e;
Notice the . contact that joins each variable with the the next / prev variable, so your line:
$display_id['Brandon']$value
should look like:
$display_id['Brandon'] . $value
^
I would do the following though.
$result .= sprintf('<li id="%s"><strong>%s</strong> %s</li>',$display_id['Brandon'] . $value,$key[1],$display_id['Murphy'] . $value);
Also using sprintf also make your code more readable.
Sorry if this is confusing. It's tough for me to put into words having beginner knowledge of PHP.
I'm using the following foreach loop:
foreach ($_POST['technologies'] as $technologies){
echo ", " . $technologies;
}
Which produces:
, First, Second, Third
What I want:
First, Second, Third
All I need is for the loop to skip the echo ", " for the first key. How can I accomplish that?
You can pull out the indices of each array item using => and not print a comma for the first item:
foreach ($_POST['technologies'] as $i => $technologies) {
if ($i > 0) {
echo ", ";
}
echo $technologies;
}
Or, even easier, you can use implode($glue, $pieces), which "returns a string containing a string representation of all the array elements in the same order, with the glue string between each element":
echo implode(", ", $_POST['technologies']);
For general case of doing something in every but first iteration of foreach loop:
$first = true;
foreach ($_POST['technologies'] as $technologies){
if(!$first) {
echo ", ";
} else {
$first = false;
}
echo $technologies;
}
but implode() is best way to deal with this specific problem of yours:
echo implode(", ", $_POST['technologies']);
You need some kind of a flag:
$i = 1;
foreach ($_POST['technologies'] as $technologies){
if($i > 1){
echo ", " . $technologies;
} else {
echo $technologies;
}
$i++;
}
Adding an answer that deals with all types of arrays using whatever the first key of the array is:
# get the first key in array using the current iteration of array_keys (a.k.a first)
$firstKey = current(array_keys($array));
foreach ($array as $key => $value)
{
# if current $key !== $firstKey, prepend the ,
echo ($key !== $firstKey ? ', ' : ''). $value;
}
demo
Why don't you simply use PHP builtin function implode() to do this more easily and with less code?
Like this:
<?php
$a = ["first","second","third"];
echo implode($a, ", ");
So as per your case, simply do this:
echo implode($_POST['technologies'], ", ");