November 6, 2012

How to dynamically create a string in PHP?

Question by All

I have a predefined pattern for building a string, which should be created regularly throughout the script.

$str="$first - $second @@ $third"; // pattern for building the string
$first="word1";
$second="word2";
$third="word3";
$string= ..?? // string should be built here based on the pattern

Currently, I am using eval to generate the string in place based on the pattern originally defined. However, as this happens occasionally and eval is generally bad, I wish to find another method.

NOTE that the pattern is defined only one time above all codes, and I can edit the pattern of all the script by one line only. Thus, what makes $string should not be touched for any change.

I tried create_function, but needs the same number of arguments. With eval, I can easily change the pattern, but with create-function, I need to change the entire script. For example, if changing the string pattern to

$str="$first @@ $second"; // One arg/var is dropped

eval Example:

$str="$first - $second @@ $third"; // Pattern is defined one-time before codes
$first="word1";
$second="word2";
$third="word3";
eval("$string = "$str";");

create_function Example:

$str=create_function('$first,$second,$third', 'return "$first - $second @@ $third";');
$string=$str($first,$second,$third);

Answer by Vulcan

You can use the string formatting capabilities offered by sprintf or vsprintf.

$format = "%s - %s @@ %s"; // pattern for building the string
$first = "word1";
$second = "word2";
$third = "word3";
$string = sprintf($format, $first, $second, $third);

You can use vsprintf if you wish to pass an array.

$format = "%s - %s @@ %s"; // pattern for building the string
$values = array($first, $second, $third);
$string = vsprintf($format, $values);

Answer by Starx

Seems to be rather simple thing to me. Use str_replace() and replace based on patterns

$str="$first$ - $second$ @@ $third$"; // pattern for building the string
$first="word1";
$second="word2";
$third="word3";

$newstr = str_replace('$first$', $first, $str);
$newstr = str_replace('$second$', $second, $newstr);
$newstr = str_replace('$third$', $third, $newstr);
April 26, 2012

eval addition with -1 doesn't work

Question by David 天宇 Wong

I’m having trouble with this js code:

$('.downvoted').live('click',function(){
var ele = $(this);
var truc = ele.prev('.score_position');

$.post('ajax/vote.php', { vote :ele.attr('title') }, function(data) {
    if(data == 'done'){
        ele.removeClass('downvoted').addClass('downvote').html('<img src="images/down.png" />');
        truc.html(eval(truc.html()+1));
    }
});
return false;
});                 

so I have this same function 3 other times for downvoting, un-upvoting and upvoting. It works well except with one exception, if truc.html() is -1 then it goes to -11 instead of 0.

Any idea why it doesn’t work? (you guys can try it here: http://91.121.154.130/?sort=last&# with id:azerty pw:azerty)

Answer by Elliot Bonneville

Don’t use eval() for this sort of work! Use parseInt, Number(...), or any of the other numerous ways of converting a value to a number in Javascript.

truc.html(parseInt(truc.html(), 10) + 1);

Note the second parameter in the parseInt function. This means you want the value passed into be parsed as a base-10 number. If you pass in a number starting with 0 into the parseInt function without specifying the radix you’ll get an unexpected and unwanted result.

Or

truc.html(Number(truc.html())+1);

Or even this:

truc.html(truc.html()*1 + 1);

This works because multiplying a string number by one results converts the variable to a number. Be careful– if the variable you multiply isn’t a valid number you’ll get NaN!

The reason you can’t simply do truc.html(truc.html()+1); is because .html() returns a string value. If you add a number to a string in Javascript, the number is simply concatenated to the string, and no math is performed. (e.g. “-1” + “1” equals “-11”).

Answer by Starx

You need to make sure the value is an integer and Use of .text() is better on this case.

parseInt(truc.text(), 10)+1
April 24, 2012

What's wrong? I am receiving error msg: Invalid arguments passed in eval()

Question by user6919

I write down my php code:

<?php
        // 已有指定 material, 顯示 material 資訊
        if (strlen($m_id) > 0) {
            // 此 material 屬於哪些 mgroup
            $group_info = $mUtil->groupInfo($m_id);
            $group_names = array();
            foreach ($group_info as $mg_id => $row) {
                if (!$row["not_in_group"]) {
                    $group_names[] = $row["mg_name"];
                }
            }
        }
    ?>

  <table width="100%">
    <tr>
      <th colspan="2"><?php echo $m_name; ?></th>
    </tr>
    <tr class="odd">
      <th>Formula</th>
      <td width="80%"><?php echo $formula; ?></td>
    </tr>
    <tr class="odd">
      <th>Alias</th>
      <td><?php echo $alias; ?></td>
    </tr>
    <tr class="odd">
      <th>In groups</th>
      <!-- join() == implode() -->
      <td><?php echo join($group_names, ",&nbsp; "); ?></td>
    </tr>
  </table><br /><br />

but I get these error message:

Notice: Undefined variable: group_names in eval() (line 97 of D:xampphtdocsdrupalmodulesphpphp.module(80) : eval()'d code).
Warning: join() [function.join]: Invalid arguments passed in eval() (line 97 of D:xampphtdocsdrupalmodulesphpphp.module(80) : eval()'d code).
Notice: Undefined variable: group_names in eval() (line 97 of D:xampphtdocsdrupalmodulesphpphp.module(80) : eval()'d code).
Warning: join() [function.join]: Invalid arguments passed in eval() (line 97 of D:xampphtdocsdrupalmodulesphpphp.module(80) : eval()'d code).

Anyone can help me? Thanks a lot….

Answer by Starx

The undefined errors are due to variables like $group_names only being defined once

if (strlen($m_id) > 0) { ... } //condition is true.

Make sure the variable you are using are instantiated before using them.

Using isset($instancename) can be one of the ways to deal with this.

Example:

if(!isset($group_names)) $group_names = array();
// ^ if $group_names is not found then at least initialize it as an empty array
//   so that the rest of the script can go easy

Also, join() needs a glue to join the array, which is not in correct order.

<?php echo join(", ", $group_names); ?>

NOTE: The use of eval() has to be however be discouraged

April 6, 2012

UTF-8 charset issues from MySQL in PHP

Question by Nick

this is really doing my nut…..

all relevant PHP Output scripts set headers (in this case only one file – the main php script):

header("Content-type: text/html; charset=utf-8");

HTML meta is set in head:

<meta http-equiv="Content-Type" content="text/html; charset=utf-8">

all Mysql tables and related columns set to:

utf8_unicode_ci     Unicode (multilingual), case-insensitive

I have been writing a class to do some translation.. when the class writes to a file using fopen, fputs etc everything works great, the correct chars appear in my output files (Which are written as php arrays and saved to the filesystem as .php or .htm files. eval() brings back .htm files correctly, as does just including the .php files when I want to use them. All good.

Prob is when I am trying to create translation entries to my DB. My DB connection class has the following line added directly after the initial connection:

 mysql_query("SET NAMES utf8, character_set_results = 'utf8', character_set_client = 'utf8', character_set_connection = 'utf8', character_set_database = 'utf8', character_set_server = 'utf8'");

instead of seeing the correct chars, i get the usual crud you would expect using the wrong charset in the DB. Eg:

Propriétés

instead of:

propriétés

don’t even get me started on Russian, Japanese, etc chars! But then using UTF8 should not make any single language charset an issue…

What have I missed? I know its not the PHP as the site shows the correct chars from the included translation .php or .htm files, its only when I am dealing with the MySQL DB that I am having these issues. PHPMyAdmin shows the entries with the wrong chars, so I assume its happening when the PHP “writes” to MySQL. Have checked similar questions here on stack, but none of the answers (all of which were taken care of) give me any clues…

Also, anyone have thoughts on speed difference using include $filename vs eval(file_get_contents($filename)).

Answer by Sebastián Grignoli

You say that you are seeing “the usual crud you would expect using the wrong charset”. But that crud is in fact created by using utf8_encode() on an already UTF8 string, so chances are that you are not using the “wrong encoding” anywhere, but exceeding the times you are encoding into UTF8.

You may take a look into a library I made to fix that kind of problems:

http://stackoverflow.com/a/3521340/290221

Answer by Starx

There is a mysql_set_charset('utf8'); in mysql for that. Run the query at the beginning of another query.

...

Please fill the form - I will response as fast as I can!