Log in

View Full Version : Image keyboard shortcut replacement thingymies



keyboard
05-23-2012, 06:29 AM
<?php
$bodytag = str_replace("$text", ":D", "<img src="../Images/grin.png" alt="Grin" />");
?>

I plan on using this (not just :D, other smilies to ) on input from a form that is stored in a database then shown in a *comments* section.

Should I run this when inserting it into the database, or when displaying it to the user (after reading it from the database).

Thanks Keyboard1333

P.s. YAY 500th POST!!!

djr33
05-23-2012, 06:44 AM
There are two options and there are good reasons for both:

Option 1: first-time, store in db
-This is more efficient because you only run the code one time.
-This doesn't allow editing later, because the raw code (original input) no longer exists.
-You don't need to worry about escaping the data again when you display it; it's ready to go (unless something else is not checked, like htmlspecialchars(), but just do that at the same time).
-This is preserved as HTML for the future in the event that you change your bbcode, so that old tags will still 'work' because they're stored as HTML-- you can never change the bbcode in such a way that it will change the formatting of old posts.

Option 2: store raw in db, re-parse every time
-Much less efficient because you must parse the code each time
-This allows re-editing as much as you'd like, because you always store (and can edit) the raw code input.
-You need to escape the data every time. (You could pre-escape some little bits, like strip all "bad" characters upon the first submission, but do NOT get stuck in a loop of > to &gt; to &amp;gt; to &amp;amp;gt; ...)/
-This will be reparsed with any updates to your bbcode system, so if you change [b] to mean "big", then all previously bold text will now be in a large font. This also means that emoticons may shift or become invalid. However, it does keep the old posts updated in case you want to edit them, and it also can allow you to do things like change the image paths, so that the old posts don't have broken HTML paths, but rather bbcode that can be automatically updated. It's a tradeoff.


The other option (which is done by some software packages I believe) is to do both. Store two versions: the original and the parsed one. Edit the original (as needed) or use it to update things as needed (eg, emoticon paths) and store the parsed version (rewriting it as needed with any changes) to save yourself the trouble of reparsing it each time. More storage, less processing, and you still can retain the old data.

keyboard
05-23-2012, 07:04 AM
Interesting.... Some good reasons for both (I don't really think the third opition is very good)
Do you have an opinion on which method is best?

djr33
05-23-2012, 07:10 AM
If your system involves editing, use the second option.
If your system does not allow editing, use the first.
If you want a system that is efficient (for processing) and also allows editing, use the third. This makes sense if the page will be generated thousands of times. Better to store it in the DB than to reprocess it each time, right? Especially if it's a complicated set of changes. If it's just a couple emoticons, that might not matter.

If it's a big serious project, I'd actually probably suggest the third option. It's more complicated (and harder) than the other two, so if either of those works for you, go for it.

keyboard
05-23-2012, 07:11 AM
But wouldn't you have to store twice as much data?

djr33
05-23-2012, 07:19 AM
Yes, twice as much. But if you re-process it each time, you have N times the number of processing. If 1000 visitors go to that page, then that's 1000x the processing. That's a lot.

I built a wiki using that method and it works well. But it's a 'big serious project' as I said above. I also was more concerned about speed than storage space in the DB. Depending on your server/hosting account, that might vary for you.

keyboard
05-23-2012, 07:34 AM
One more question on this topic -


$shortcut[0] = ":)";
$shortcut[1] = ":(";
$shortcut[2] = ":D";
$shortcut[3] = ":P";
$shortcut[4] = ":o";
$shortcut[5] = "o..o";

$emoticion[0] = "Images/smile.png";
$emoticion[1] = "Images/sad.png";
$emoticion[2] = "Images/grin.png";
$emoticion[3] = "Images/tongue.png";
$emoticion[4] = "Images/gasp.png";
$emoticion[5] = "Images/embarrassed.png";

$text = str_replace("$emoticion", "$shortcut", "$text");


But


$text = str_replace(":D", "Images/grin.png", "$text");

Does? Any help?

djr33
05-23-2012, 07:40 AM
Use a foreach loop. Also, store the symbols and replacements as keys and values.
(As is, you'd need to use a for loop, from 0-5.)

keyboard
05-23-2012, 07:44 AM
Also, store the symbols and replacements as keys and values.


What do you mean by that?
Thanks, Keyboard1333


Edit - 3 {


$shortcut[0] = ":)";
$shortcut[1] = ":(";
$shortcut[2] = ":D";
$shortcut[3] = ":P";
$shortcut[4] = ":o";
$shortcut[5] = "o..o";

$emoticon[0] = "Images/smile.png";
$emoticon[1] = "Images/sad.png";
$emoticon[2] = "Images/grin.png";
$emoticon[3] = "Images/tongue.png";
$emoticon[4] = "Images/gasp.png";
$emoticon[5] = "Images/embarrassed.png";
for ($counter = 0; $counter <= count($shortcut); $counter += 1) {
$emoticonPath = "<img src='" . $emoticon[$counter] . "' />";
$text = str_replace("$shortcut[$counter]", "$emoticonPath", "$text");
}

I then insert $text into a db... but nothing is inserted and for the life of me I can't work out what I'm doing wrong. Any help?

djr33
05-23-2012, 05:44 PM
Here's (roughly) how I'd organize it:


$replacements = array(
':D' => 'URL',
':)' => 'URL',
':(' => 'URL'
//....
);

foreach ($replacements as $key=>$value) {
$text = str_replace($key, '<img src="'.$value.'">', $text);
}

The basic method you have above could work too, but you are using quotes incorrectly. You can't use "$array['key']" because it will not recognize that as a variable, but as a literal string. Use "{$array['key']}" if you must, or just skip the quotes. There's absolutely no reason to use "$var" rather than just $var. It just makes it slower and makes the code harder to write/read.

keyboard
05-23-2012, 09:12 PM
Thanks Daniel!

One more thing - why do you have to use a for loop when it says here (http://php.net/manual/en/function.str-replace.php) that it takes arrays for both the first and second parameters?

djr33
05-23-2012, 11:39 PM
It's simpler.

I like storing the items as keys and values so that they're next to each other (see my last post). If you store them in separate arrays, you could use your method, just with str_replace(), actually.

If you want to use my method and skip the loop, you'd have to do this (which would work fine):

$text = str_replace(array_keys($replacements),array_values($replacements),$text);

Note that in terms of processing time, it's probably about the same as the loop (because in reality the loop will happen anyway, within str_replace() because you're using arrays). It's slightly shorter and arguably 'simpler' code, but I think it's also a little harder because knowing those functions requires more familiarity with PHP-- so do whatever works for you. Personally if I'm at all unsure I prefer to use my own loops so I know exactly what's going on and I don't need to look up details for functions.