I am getting a error using php (str_replace) - php

I am getting a error while using php str_replace function.
I am reading out a string in a different file a JSON
and if I remove the str_replace part it works without the error but I want to make the ** go to bold if there are any other ways you know you can also just tell that.
<?php
$data = json_decode($readjson, true);
echo "<br/><br<br/>";
foreach ($data as $emp) {
echo str_replace("**","<strong>","$data"), $emp['message']."<br/>";
}
?>
And the output is
Notice: Array to string conversion in C:\Users\k-ver\Dropbox\Other\website stuff or smth\r3mind3r\changelog.php on line 16
Array - Weekley Update - Another great week at our side! We have made enournous advances in synching with the raspberry pi (the computer we are going to host from) and are closer than ever to our promised release We have also been fixing on the mute commands and are very close to making it work, aswell with unmute command.language feature is closing up on complete and about 70% of the bot has the language system working. We also made a new system that should be easier to use for bouth us devs and the translators. All thats left for the release atm is: -finishing synching -fixing the mute command and unmute command -make a functioning permissonlevel system -adding those last 30% of the bot that does not have the translationsystem in place. and the bot will have its huge release! (about time if you asked me)
(it is for a dev log)
and the part I don't understand is the notice and I also don't understand how to fix it
It would be awesome if you guys would like to help me.

This variable should be string value e.g $emp['message'] not the multi-dimensional array $data.
// see this line with $emp['message'] not $data array
str_replace("**","<strong>",$emp['message']);
EDIT: As per comment
<?php
$string = '{
"188762891137056769": {
"message": "\n**- Weekley Update -**\nAnother great week at our side! \nWe have made enournous advances in synching with the raspberry pi *(the computer we are going to host from)* and are closer than ever to our promised release\n\nWe have also been fixing on the mute commands and are very close to making it work, aswell with unmute command.language feature is closing \nup on complete and about 70% of the bot has the language system working. We also made a new system that should be easier to use for bouth \nus devs and the translators.\n\n**All thats left for the release atm is:**\n-finishing synching \n-fixing the mute command and unmute command \n-make a functioning permissonlevel system\n-adding those last 30% of the bot that does not have the translationsystem in place. \n\nand the bot will have its huge release! *(about time if you asked me)*"
}
}';
$array = json_decode($string,1);
$message = $array['188762891137056769']['message'];
$re = '/\*\*(.*?)\*\*/m';
$subst = '<strong>$1</strong>';
echo preg_replace($re, $subst, $message);
?>
DEMO: https://3v4l.org/ovhGq

You used array inside str_replace("**","","$data") this is wrong, how you can fix it just replace $data with $emp

Your code is:
foreach ($data as $emp) {
echo str_replace("**","<strong>","$data"), $emp['message']."<br/>";
}
You see $data is an array, an $emp is the current element within the foreach loop.
So, you should do: str_replace("", "", $emp)
By the way, I see this: $emp['message'], which means $emp is an array too?
Maybe you should post the $readjson variable, so we'll know what type of data is.

If you want to enclose the text between ** with <strong></strong>, you need to use a regex. Here is a little code that does what you want :
function boldify($text) {
return preg_replace('/\*\*((.|\n|\r)*)\*\*/imU', '<strong>$1</strong>', $text);
}
Basically, it uses the function preg_replace to replace according to the regex (the first parameter).
How does this regex work :
1) You have \*\* at the beginning because that's your "opening tag". (* is a special regex character, so it needs escaping.)
2) You have ((.|\n|\r)*).
The inner part : .|\n|\r says "Catch me any character (the .) or (the |) a line feed (the \n) or a carriage return (the \r).".
Then you have the inner part enclosed with (inner part)*. This says "Match the inner part any number of time.".
Finally, you have the "middle part" enclosed with (middle part). This says "Remember what you just caught inside the parentheses, we will need it for the replace.
3) You have \*\* again.
4) All this is enclosed by /regex/imU.
The / are just there to say where the regex actually is.
The imU are flags: i is ignore case, m multiline, U ungreedy.
i are m are pretty straightforward, but U says "catch the smallest group possible".
As the second parameter you have '<strong>$1</strong>'. $1 is the group we remember from 2).
The third parameter is the subject.
I hope it was clear.
You can just use it like this :
echo boldify($emp['message']);

Related

PHP variables look the same but are not equal (I'm confused)

OK, so I shave my head, but if I had hair I wouldn't need a razor because I'd have torn it all out tonight. It's gone 3am and what looked like a simple solution at 00:30 has become far from it.
Please see the code extract below..
$psusername = substr($list[$count],16);
if ($psusername == $psu_value){
$answer = "YES";
}
else {
$answer = "NO";
}
$psusername holds the value "normann" which is taken from a URL in a text based file (url.db)
$psu_value also holds the value "normann" which is retrieved from a cookie set on the user's computer (or a parameter in the browser address bar - URL).
However, and I'm sure you can guess my problem, the variable $answer contains "NO" from the test above.
All the PHP I know I've picked up from Google searches and you guys here, so I'm no expert, which is perhaps evident.
Maybe this is a schoolboy error, but I cannot figure out what I'm doing wrong. My assumption is that the data types differ. Ultimately, I want to compare the two variables and have a TRUE result when they contain the same information (i.e normann = normann).
So if you very clever fellows can point out why two variables echo what appears to be the same information but are in fact different, it'd be a very useful lesson for me and make my users very happy.
Do they echo the same thing when you do:
echo gettype($psusername) . '\n' . gettype($psu_value);
Since i can't see what data is stored in the array $list (and the index $count), I cannot suggest a full solution to yuor problem.
But i can suggest you to insert this code right before the if statement:
var_dump($psusername);
var_dump($psu_value);
and see why the two variables are not identical.
The var_dump function will output the content stored in the variable and the type (string, integer, array ec..), so you will figure out why the if statement is returning false
Since it looks like you have non-printable characters in your string, you can strip them out before the comparison. This will remove whatever is not printable in your character set:
$psusername = preg_replace("/[[:^print:]]/", "", $psusername);
0D 0A is a new line. The first is the carriage return (CR) character and the second is the new line (NL) character. They are also known as \r and \n.
You can just trim it off using trim().
$psusername = trim($psusername);
Or if it only occurs at the end of the string then rtrim() would do the job:
$psusername = rtrim($psusername);
If you are getting the values from the file using file() then you can pass FILE_IGNORE_NEW_LINES as the second argument, and that will remove the new line:
$contents = file('url.db', FILE_IGNORE_NEW_LINES);
I just want to thank all who responded. I realised after viewing my logfile the outputs in HEX format that it was the carriage return values causing the variables to mismatch and a I mentioned was able to resolve (trim) with the following code..
$psusername = preg_replace("/[^[:alnum:]]/u", '', $psusername);
I also know that the system within which the profiles and usernames are created allow both upper and lower case values to match, so I took the precaution of building that functionality into my code as an added measure of completeness.
And I'm happy to say, the code functions perfectly now.
Once again, thanks for your responses and suggestions.

delete all bug string between two words

I've got a script which generates text. I need to be strip all repeated blocks of text. The string is in xml format, so I can use the beginning and ending tags to determine where the strings are. I've been using substr_replace to remove the unnecessary text... However, this only works if I know how many times said text is going to be present in the string. Example :
<container>
<string1>This is the first string.</string>
<string2>This is the second string.</string>
<stuff>This is the important stuff.</stuff>
</container>
That container might appear once, twice six times, seven times, whatever. The point is, it's necessary to only have it appear once in the string variable. Right now this is what I'm doing.
$where_begin = strpos($wsman_output,'<container');
$where_end = strpos($wsman_output,"</container>");
$end_length = strlen("</Envelope>");
$attack = $where_end - $where_begin;
$attack = $attack + $end_length;
$wsman_output = substr_replace($wsman_output,"",$where_begin,$attack);
And I do that for each time the container exists.... However, I just found out that it's not always going to be the same.. Which really messes things up.
Any ideas?
In the end I decided to use the method suggested here.
I pulled each block of string I wanted from the variable, then combined them back together in the required order.

PHP preg_replace inside for loop

I'm currently trying out this PHP preg_replace function and I've run into a small problem. I want to replace all the tags with a div with an ID, unique for every div, so I thought I would add it into a for loop. But in some strange way, it only do the first line and gives it an ID of 49, which is the last ID they can get. Here's my code:
$res = mysqli_query($mysqli, "SELECT * FROM song WHERE id = 1");
$row = mysqli_fetch_assoc($res);
mysqli_set_charset("utf8");
$lyric = $row['lyric'];
$lyricHTML = nl2br($lyric);
$lines_arr = preg_split('[<br />]',$lyricHTML);
$lines = count($lines_arr);
for($i = 0; $i < $lines; $i++) {
$string = preg_replace(']<br />]', '</h4><h4 id="no'.$i.'">', $lyricHTML, 1);
echo $i;
}
echo '<h4>';
echo $string;
echo '</h4>';
How it works is that I have a large amount of text in my database, and when I add it into the lyric variable, it's just plain text. But when I nl2br it, it gets after every line, which I use here. I get the number of by using the little "lines_arr" method as you can see, and then basically iterate in a for loop.
The only problem is that it only outputs on the first line and gives that an ID of 49. When I move it outside the for loop and removes the limit, it works and all lines gets an <h4> around them, but then I don't get the unique ID I need.
This is some text I pulled out from the database
Mama called about the paper turns out they wrote about me
Now my broken heart´s the only thing that's broke about me
So many people should have seen what we got going on
I only wanna put my heart and my life in songs
Writing about the pain I felt with my daddy gone
About the emptiness I felt when I sat alone
About the happiness I feel when I sing it loud
He should have heard the noise we made with the happy crowd
Did my Gran Daddy know he taught me what a poem was
How you can use a sentence or just a simple pause
What will I say when my kids ask me who my daddy was
I thought about it for a while and I'm at a loss
Knowing that I´m gonna live my whole life without him
I found out a lot of things I never knew about him
All I know is that I´ll never really be alone
Cause we gotta lot of love and a happy home
And my goal is to give every line an <h4 id="no1">TEXT</h4> for example, and the number after no, like no1 or no4 should be incremented every iteration, that's why I chose a for-loop.
Looks like you need to escape your regexp
preg_replace('/\[<br \/\]/', ...);
Really though, this is a classic XY Problem. Instead of asking us how to fix your solution, you should ask us how to solve your problem.
Show us some example text in the database and then show us how you would like it to be formatted. It's very likely there's a better way.
I would use array_walk for this. ideone demo here
$lines = preg_split("/[\r\n]+/", $row['lyric']);
array_walk($lines, function(&$line, $idx) {
$line = sprintf("<h4 id='no%d'>%s</h4>", $idx+1, $line);
});
echo implode("\n", $lines);
Output
<h4 id="no1">Mama called about the paper turns out they wrote about me</h4>
<h4 id="no2">Now my broken heart's the only thing that's broke about me</h4>
<h4 id="no3">So many people should have seen what we got going on</h4>
...
<h4 id="no16">Cause we gotta lot of love and a happy home</h4>
Explanation of solution
nl2br doesn't really help us here. It converts \n to <br /> but then we'd just end up splitting the string on the br. We might as well split using \n to start with. I'm going to use /[\r\n]+/ because it splits one or more \r, \n, and \r\n.
$lines = preg_split("/[\r\n]+/", $row['lyric']);
Now we have an array of strings, each containing one line of lyrics. But we want to wrap each string in an <h4 id="noX">...</h4> where X is the number of the line.
Ordinarily we would use array_map for this, but the array_map callback does not receive an index argument. Instead we will use array_walk which does receive the index.
One more note about this line, is the use of &$line as the callback parameter. This allows us to alter the contents of the $line and have it "saved" in our original $lyrics array. (See the Example #1 in the PHP docs to compare the difference).
array_walk($lines, function(&$line, $idx) {
Here's where the h4 comes in. I use sprintf for formatting HTML strings because I think they are more readable. And it allows you to control how the arguments are output without adding a bunch of view logic in the "template".
Here's the world's tiniest template: '<h4 id="no%d">%s</h4>'. It has two inputs, %d and %s. The first will be output as a number (our line number), and the second will be output as a string (our lyrics).
$line = sprintf('<h4 id="no%d">%s</h4>', $idx+1, $line);
Close the array_walk callback function
});
Now $lines is an array of our newly-formatted lyrics. Let's output the lyrics by separating each line with a \n.
echo implode("\n", $lines);
Done!
If your text in db is in every line why just not explode it with \n character?
Always try to find a solution without using preg set of functions, because they are heavy memory consumers:
I would go lke this:
$lyric = $row['lyric'];
$lyrics =explode("\n",$lyrics);
$lyricsHtml=null;
$i=0;
foreach($lyrics as $val){
$i++;
$lyricsHtml[] = '<h4 id="no'.$i.'">'.$val.'</h4>';
}
$lyricsHtml = implode("\n",$lyricsHtml);
An other way with preg_replace_callback:
$id = 0;
$lyric = preg_replace_callback('~(^)|$~m',
function ($m) use (&$id) {
return (isset($m[1])) ? '<h4 id="no' . ++$id . '">' : '</h4>'; },
$lyric);

Does PHP str_replace have a greater than 13 character limit?

This works up until the 13th character is hit. Once the str_ireplace hits "a" in the cyper array, the str_ireplace stops working.
Is there a limit to how big the array can be? Keep in mind if type "abgf" i get "nots", but if I type "abgrf" when I should get "notes" I get "notrs". Racked my brain cant figure it out.
$_cypher = array("n","o","p","q","r","s","t","u","v","w","x","y","z","a","b","c","d","e","f","g","h","i","j","k","l","m");
$_needle = array("a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z");
$_decryptedText = str_ireplace($_cypher, $_needle, $_text);
echo $_decryptedText;
Help?
Use strtrDocs:
$_text = 'abgrf';
$translate = array_combine($_cypher, $_needle);
$_decryptedText = strtr($_text, $translate);
echo $_decryptedText; # notes
Demo
But, was there something I was doing wrong?
It will replace each pair, one pair after the other on the already replaced string. So if you replace a character that you replace again, this can happen:
r -> e e -> r
abgrf -> notes -> notrs
Your e-replacement comes after your r-replacement.
Take a peak at the docs for str_replace. Namely the following line:
Because str_replace() replaces left to right, it might replace a previously inserted value when doing multiple replacements. See also the examples in this document.
So it's working as told. It's just doing a circular replacement (n -> a, then a -> n).
Use str_rot13
although it appears to be a straight rot13, if it is not, another option is to use strtr(). You provide a string and an array of replacement pairs and get the resulting translation back.

how to eval() a segment of a string

I have a string that has HTML & PHP in it, when I pull the string from the database, it is echo'd to screen, but the PHP code doesn't display. The string looks like this:
$string = 'Hello <?php echo 'World';?>';
echo $string;
Output
Hello
Source Code
Hello <?php echo 'World';?>
When I look in the source code, I can see the php line there. So what I need to do is eval() just the php segment that is in the string.
One thing to consider is that the PHP could be located anywhere in the string at any given time.
* Just to clarify, my PHP config is correct, this is a case of some PHP being dumped from the database and not rendering, because I am echo'ing a variable with the PHP code in it, it fails to run. *
Thanks again for any help I may receive.
$str = "Hello
<?php echo 'World';?>";
$matches = array();
preg_match('/<\?php (.+) \?>/x', $str, $matches);
eval($matches[1]);
This will work, but like others have and will suggest, this is a terrible idea. Your application architecture should never revolve around storing code in the database.
Most simply, if you have pages that always need to display strings, store those strings in the database, not code to produce them. Real world data is more complicated than this, but must always be properly modelled in the database.
Edit: Would need adapting with preg_replace_callback to remove the source/interpolate correctly.
You shouldn't eval the php code, just run it. It's need to be php interpreter installed, and apache+php properly configured. Then this .php file should output Hello World.
Answer to the edit:
Use preg_replace_callback to get the php part, eval it, replace the input to the output, then echo it.
But. If you should eval things come from database, i'm almost sure, it's a design error.
eval() should work fine, as long as the code is proper PHP and ends with a semicolon. How about you strip off the php tag first, then eval it.
The following example was tested and works:
<?php
$db_result = "<?php echo 'World';?>";
$stripped_code = str_replace('?>', '', str_replace('<?php', '', $db_result));
eval($stripped_code);
?>
Just make sure that whatever you retrieve from the db has been properly sanitized first, since you're essentially allowing anyone who can get content into the db, to execute code.

Categories