PHP str_replace with associate array - php

I have a row returned from DB and i need to change the specific markup characters used in cols to the right characters for the display:
$row = mysqli_fetch_array($res, MYSQLI_ASSOC); //the result of query is 1 row
$markup = array("#", "#", "&", "$"); // this is our markup
$meaning = array("↑", "↓", "(dil.)", "(conc.)"); // this is our meaning of the markup for the display
foreach ($row as $k => $v) { //for each element of the array we change one char for the other
$v = str_replace ($markup, $meaning, $v);
echo "<br>$v";
}
UPD now its getting more weird. I did a mistake by tracing if the str_replace before the change was made to array, i fixed it ant tracing shows that it works! But there is a specialised output of this array down below and it still appears with unreplaced characters!
$reagent_no = "reaction_l" . $i; // determining the column number, irrelevant to the issue
echo "<td>\n<h3>{$row[$reagent_no]}</h3></td>"; //output of the supposedly
//changed characters, but it still outputs the markup, as if i didnt do anything to the array previously

You are first printing the variable and then using the str_replace() function. Change it to:-
foreach ($row as $k => $v) { //for each element of the array we change one char for the other
$v = str_replace ($markup, $meaning, $v);
echo "<br>$v";
}

The problem is that the str_replace is executed after the echo.
Try:
foreach ($row as $k => $v) { //for each element of the array we change one char for the other
$v = str_replace ($markup, $meaning, $v);
echo "<br>$v";
}

Related

In_array not working - compare two files

The code below is a simple version of what I am trying to do. The code will read in two files, see if there is a matching entry and, if there is, display the difference in the numbers for that item. But it isn't working. The first echo displays the word but the second echo is never reached. Would someone please explain what I am missing?
$mainArry = array('Albert,8');
$arry = array('Albert,12');
foreach ($arry as $line) {
$kword = explode(',', $line);
echo 'kword '.$kword[0];
if (in_array($kword[0], $mainArry)) {
echo 'line '.$line. ' has count of '.$kword[1] . '<br>';
}
}
Your $mainArry contains a single element: the string 'Albert,8'. It looks like you want to use it as an array (elements 'Albert' and '8') instead of a string.
You mention the code will read from two files, so you can 'explode' it to a real array, as you do with $arry. A simpler approach would be using str_getcsv() to parse the CSV string into $mainArry.
$inputString = 'Albert,8';
$mainArry = str_getcsv($inputString); // now $mainArry is ['Albert','8']
$arry = array('Albert,12');
foreach ($arry as $line) {
$kword = explode(',', $line);
echo 'kword '.$kword[0];
if (in_array($kword[0], $mainArry)) {
echo 'line '.$line. ' has count of '.$kword[1] . '<br>';
}
}
Test it here.
You are attempting to compare the string Albert with Albert,8, so they won't match. If you want to check if the string contains the keyword, assuming your array has more than one element, you could use:
$mainArry = array('Albert,8');
$arry = array('Albert,12');
foreach ($arry as $line) {
$kword = explode(',', $line);
echo 'kword '.$kword[0];
foreach ($mainArry as $comp) {
if (strstr($comp, $kword[0])) {
echo 'line '.$line. ' has count of '.$kword[1] . '<br>';
}
}
}
example: https://eval.in/728566
I don't recommend your way of working, but this is a solution, basically the process you apply to the $arry should also apply to the $mainArry you're trying to compare it to.
$mainArry = array('Albert,8');
$arry = array('Albert,12');
/***
NEW function below takes the valus out of the main array.
and sets them in their own array so they can be properly compared.
***/
foreach ($mainArry as $arrr){
$ma = explode(",",$arrr);
$names[] = $ma[0];
$values[] = $ma[1];
}
unset($arrr,$ma);
foreach ($arry as $line) {
$kword = explode(',', $line);
echo 'kword '.$kword[0];
/// note var reference here is updated.
if (in_array($kword[0], $names)) {
echo '<br>line '.$kword[0]. ' has count of '.$kword[1] . '<br>';
}
}
Yeah, MarcM's answer above does the same thing in a neat single line, but I wanted to illustrate a little more under the hood operations of the value setting. :-/

How to trim the whitespace from an array in PHP

I'm trying to parse a CSV file and as part of it I would like to remove leading/trailing whitespace from all of my cells. Since it's a CSV file it's formatted like a 2D array. Initially I tried:
foreach($csv as $row){
foreach($row as $cell){
$cell = trim($cell);
}
}
However the result was untrimmed.
Next I tried using array_map as suggested here.
$csv = array_map('trim', $csv);
This gave me back an array of empty rows. So I also tried
foreach($csv as $row){
$row = array_map('trim', $row);
}
Which like my first attempt didn't change anything.
Here's the CSV data I'm using as my input:
First Name,Last Name,Contact Method,Phone, Email
John,Doe,Email,1-XXX-XXX-XXXX, john#example.com
Jane,Doe,Phone Call,1-XXX-XXX-XXXX,jane#example.com
In particular I was trying to get my script to trim the leading space in the last cell of the first row (" Email" => "Email").
You are not modifying the original array when you do the trim. You should get the values by reference in the foreach loop.
foreach($csv as &$row){
foreach($row as &$cell){
$cell = trim($cell);
}
}
From the documentation:
In order to be able to directly modify array elements within the loop
precede $value with &. In that case the value will be assigned by
reference.
You need to reference $row in order to make changes to the array (note the &):
foreach($csv as &$row){
$row = array_map('trim', $row);
}
If you are seeing it like you put here,
" Email" => "Email"
you'll have to trim it from the key, can you show how you are assigning the named headers. Because I would trim it there, but using array_map('trim', $data) will remove the whitespace, I do that all day long.
Well to just clean the keys you can do,
$keys = array_map( 'trim', array_keys($data) );
$data = array_combine( $keys, $data );
$input = [
'parent' => [
'child' => ' element to be trimmed '
]
];
array_walk_recursive($input, function (&$item) {
if (!is_array($item)) {
$item = trim($item);
}
});

PHP - Search array for string

I have a page with a form where I post all my checkboxes into one array in my database.
The values in my database looks like this: "0,12,0,15,58,0,16".
Now I'm listing these numbers and everything works fine, but I don't want the zero values to be listed on my page, how am I able to search through the array and NOT list the zero values ?
I'm exploding the array and using a for each loop to display the values at the moment.
The proper thing to do is to insert a WHERE statement into your database query:
SELECT * FROM table WHERE value != 0
However, if you are limited to PHP just use the below code :)
foreach($values AS $key => $value) {
//Skip the value if it is 0
if($value == 0) {
continue;
}
//do something with the other values
}
In order to clean an array of elements, you can use the array_filter method.
In order to clean up of zeros, you should do the following:
function is_non_zero($value)
{
return $value != 0;
}
$filtered_data = array_filter($data, 'is_non_zero');
This way if you need to iterate multiple times the array, the zeros will already be deleted from them.
you can use array_filter for this. You can also specify a callback function in this function if you want to remove items on custom criteria.
Maybe try:
$out = array_filter(explode(',', $string), function ($v) { return ($v != 0); });
There are a LOT of ways to do this, as is obvious from the answers above.
While this is not the best method, the logic of this might be easier for phpnewbies to understand than some of the above methods. This method could also be used if you need to keep your original values for use in a later process.
$nums = '0,12,0,15,58,0,16';
$list = explode(',',$nums);
$newList = array();
foreach ($list as $key => $value) {
//
// if value does not equal zero
//
if ( $value != '0' ) {
//
// add to newList array
//
$newList[] = $value;
}
}
echo '<pre>';
print_r( $newList );
echo '</pre>';
However, my vote for the best answer goes to #Lumbendil above.
$String = '0,12,0,15,58,0,16';
$String = str_replace('0', '',$String); // Remove 0 values
$Array = explode(',', $String);
foreach ($Array AS $Values) {
echo $Values."<br>";
}
Explained:
You have your checkbox, lets say the values have been converted into a string. using str_replace we have removed all 0 values from your string. We have then created an array by using explode, and using the foreach loop. We are echoing out all the values of th array minux the 0 values.
Oneliner:
$string = '0,12,0,15,58,0,16';
echo preg_replace(array('/^0,|,0,|,0$/', '/^,|,$/'), array(',', ''), $string); // output 12,15,58,16

How to only show the first line of print print_r?

How do you echo only the first line of print print_r?
More info:
I have this PHP code:
preg_match_all('/MbrDtlMain.php\?([^ ]+)>/i', $string, $matches);
foreach(end($matches) as $key=> $value){
print print_r($value, 1).'<br>';
}
That results in:
12567682
12764252
12493678
14739908
(or other numbers depending on user input)
I tried:
preg_match_all('/MbrDtlMain.php\?([^ ]+)>/i', $string, $matches);
foreach(end($matches) as $key=> $value){
$id = print_r($value, 1).'<br>';
}
echo $id
But it results in 1 random number from the list. In other words, the result only shows when using print like ' print print_r($value, 1).'<br>';'. The problem is that I only want the first, inorder, result to be shown. As if:
$firstlineofnumbers = '12567682';
echo $firstlineofnumbers;
Hope this makes sense. Thanks (:
If I understood what you're trying to do, just adding a break; statement after outputting the first value should be enough:
foreach(end($matches) as $key=> $value){
print print_r($value, true).'<br>'; // print_r() expects true, not 1
break;
}
If the keys in $matches are always numeric keys, this code should be enough:
echo $matches[0];
Otherwise, try this code:
$keys = array_keys($matches);
echo $matches[array_shift($keys)];
$keys will contain all keys of $matches.
array_shift will return the first value of $keys (the first key).
So the last line will display the corresponding value.
There is no need to loop through the entire array if you only need to display the first element.
preg_match_all('/MbrDtlMain.php\?([^ ]+)>/i', $string, $matches);
$i=0;
foreach(end($matches) as $key=> $value){
$i++;
if ($i == 1) {
echo $value."<br />";
}
}
This starts with the variable $i which increases by 1 for each match. If $i == 1, then it will echo the $value.

How to handle my data?

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);
}
}

Categories