Recently I was asked to write my own implementation of PHP serialize(), unserialize() functions. My functions should return identical results as original PHP internal functions.
I made some progress with serialize() function :
<?php
function serializator($input)
{
$args = count(func_get_args());
if ( $args > 1) { throw new Exception("Serializator function requires exactly 1 parameter. {$args} given"); };
switch ($input) :
case is_array($input) :
$length = count($input);
$str = gettype($input)[0] . ':' . $length . ':{';
foreach ($input as $key => $value):
if (is_array($value)) {
$str .= gettype($key)[0] . ':' ;
$str .= !is_int($key) ? strlen($key) . ':' . '"' . $key . '"' . ';' : $key . ';';
$str .= serializator($value);
}
else {
$str .= gettype($key)[0] . ':' ;
$str .= !is_int($key) ? strlen($key) . ':' . '"' . $key . '"' . ';' : $key . ';';
$str .= gettype($value)[0] . ':' ;
$str .= !is_int($value) ? strlen($value) . ':' . '"' . $value . '"' . ";" : $value . ';';
}
endforeach;
$str .= '}';
break;
case is_object( $input ) :
$str = ucfirst(gettype($input)[0]) . ':' . strlen(get_class($input)) . ':' . '"' . get_class($input) . '"';
$str .= substr(serializator((array)$input), 1);
break;
case is_int( $input) || is_bool($input) || is_null($input) :
$str = gettype($input)[0] . ':' . $input;
break;
case is_string( $input) :
$str = gettype($input)[0] . ':' . strlen($input). ':' . '"' . $input . '"';
break;
case is_float($input) :
$precision = ini_get('serialize_precision');
$str = gettype($input)[0] . ':' . $input;
break;
case is_resource($input):
$str = 'i:0'; // resource is not serializable
break;
default:
return false;
endswitch;
return $str;
}
But struggling with unserialize() implementation. Could anyone point out from where to start thinking or looking? :) Thanks.
Related
I want to add a newline in a textarea. I tried with < p> tag but it's not working. Can you help me to insert a newline in a textarea? Please find the code above for a generic contact form. Where should I add tags for line breaks here?
public function cs_form_textarea_render($params = '') {
global $post, $pagenow;
extract($params);
if ( $pagenow == 'post.php' ) {
$cs_value = get_post_meta($post->ID, 'cs_' . $id, true);
} else {
$cs_value = $std;
}
if ( isset($cs_value) && $cs_value != '' ) {
$value = $cs_value;
} else {
$value = $std;
}
$cs_rand_id = time();
if ( isset($force_std) && $force_std == true ) {
$value = $std;
}
$html_id = ' id="cs_' . sanitize_html_class($id) . '"';
$html_name = ' name="cs_' . sanitize_html_class($id) . '"';
if ( isset($array) && $array == true ) {
$html_id = ' id="cs_' . sanitize_html_class($id) . $cs_rand_id . '"';
$html_name = ' name="cs_' . sanitize_html_class($id) . '_array[]"';
}
$cs_required = '';
if ( isset($required) && $required == 'yes' ) {
$cs_required = ' required="required"';
}
$cs_output = '<div class="' . $classes . '">';
$cs_output .= ' <textarea' . $cs_required . ' rows="5" cols="30"' . $html_id . $html_name . ' placeholder="' . $name . '">' . sanitize_text_field($value) . '</textarea>';
$cs_output .= $this->cs_form_description($description);
$cs_output .= '</div>';
if ( isset($return) && $return == true ) {
return force_balance_tags($cs_output);
} else {
echo force_balance_tags($cs_output);
}
}
Just add a "\n" char somewhere between your text area tags
$cs_output .= ' <textarea' . $cs_required . ' rows="5" cols="30"' . $html_id . $html_name . ' placeholder="' . $name . '">' . sanitize_text_field($value) . "\n" . "this text is on a new line". '</textarea>';
You will try to add "\n" before your end position of the tag. You need to concatenate Like ."\n".
This is my PHP
$val = "";
foreach($data as $v){
$val .= '"' . $v . "\n" . '"';
}
The result is
//this is inside of cell
sample
"sample
"sample
This is correct but I cant figure out how to remove the double quote in "sample. Only the first value dont have a double quote the rest will have a double quote.
EDIT
This is the result of my code
This is what I want
Just Remove some part of your code, you will get solution:
$val = "";
foreach($data as $v){
$val .= $v . "\n";
}
Just try (Maintaining line break in excel):
$val = "";
foreach($data as $v){
$val .= $v . "<br style='mso-data-placement:same-cell;' />";
}
Somthing like this should do the trick
$i = 0
foreach($data as $v){
$val .= '"' . $v . "\n" . (count($data) !== $i) ? '"' : '';
$i++;
}
I think you can use the php function trim like this:
$val = "";
foreach($data as $v){
if( ''==$val) {
$val .= trim('"' . $v . "\n" . '"','"');
}else{
$val .= '"' . $v . "\n" . '"','"';
}
}
$val .= '"' . $v . "</br>" . '"';
$val=str_replace('"','',$val);
I think this is what you are looking for inside your loop. It will remove every double quote.
Well there you go :
$data = ['sample','sample','sample'];
$val = "";
foreach($data as $v){
$val .= $v . "\n" ;
}
Then you simply use fputcsv() like this :
$fp = fopen('file.csv', 'w');
fputcsv($fp, [$val]);
And you get the result you want :
The answer to my question is
$val = "";
foreach($data as $v){
$val .= $v . "\n";
}
$val = '"'. $val .'"';
I need to add the '"' outside of the loop.
I recenlythave tried to convert the preg_replace() line to preg_replace_callback, but with no success. I did try the methods on Stackoverflow, but they seem to be different.
Hope I could get some help with it.
function ame_process_bbcode(&$parser, &$param1, $param2 = '')
{
if (class_exists('vB_BbCodeParser_Wysiwyg') AND is_a($parser, 'vB_BbCodeParser_Wysiwyg'))
{
return $text;
}
else
{
global $vbulletin;
($hook = vBulletinHook::fetch_hook('automediaembed_parse_bbcode_start')) ? eval($hook) : false;
$ameinfo = fetch_full_ameinfo();
$text = preg_replace($ameinfo['find'], $ameinfo['replace'], ($param2 ? $param2 : $param1), 1);
($hook = vBulletinHook::fetch_hook('automediaembed_parse_bbcode_end')) ? eval($hook) : false;
return $text;
}
}
Updates: Thanks to #Barmar, I know now that the issue is related to the fetch_full_ameinfo function.. I will add function below. Maybe it will help others in the long run. I will also include the fix whenever I am done. Thanks to #Barmar for the help.
function &fetch_full_ameinfo($findonly = false, $refresh = false)
{
global $db, $vbulletin, $vbphrase, $stylevar;
static $ameinfo = array();
static $inied, $lastfind;
if ($refresh)
{
$inied = false;
}
if ($lastfind && !$findonly)
{
$inied = false;
$ameinfo = array();
}
if (!$inied)
{
if (!$refresh AND $vbulletin->options['automediaembed_cache'])
{
$path = $vbulletin->options['automediaembed_cache_path'];
if (file_exists($path . "findonly.php"));
{
if ($findonly)
{
include($path . "findonly.php");
}
else
{
include($path . "ameinfo.php");
}
$inied = true;
$lastfind = $findonly;
return $ameinfo;
}
}
if ($vbulletin->options['automediaembed_resolve'])
{
$embed = ",IF(extraction=1 AND embedregexp!= '', embedregexp, '') as embedregexp, IF(extraction=1 AND validation!= '', validation, '') as validation";
$embedwhere = " AND ((extraction = 0 AND embedregexp = '') OR (extraction = 1)) ";
}
else
{
$embedwhere = " AND embedregexp = ''";
}
$sql = "SELECT findcode" . (!$findonly ? ", replacecode,title,container,ameid" : ",extraction$embed") . " FROM " . TABLE_PREFIX . "automediaembed WHERE status=1 $embedwhere
ORDER BY displayorder, title ASC";
$results = $db->query_read_slave($sql);
while ($result = $db->fetch_array($results))
{
if ($result['findcode'])
{
if (!$findonly)
{
$ameinfo['find'][] = "~($result[findcode])~ie";
$ameinfo['replace'][] = 'ame_match_bbcode($param1, $param2, \'' . $result['ameid'] . '\', \'' . ame_slasher($result['title']) . '\', ' . $result['container'] . ', \'' . ame_slasher($result['replacecode']) . '\', \'\\1\', \'\\2\', \'\\3\', \'\\4\', \'\\5\', \'\\6\')';
}
else
{
$ameinfo['find'][] = "~(\[url\]$result[findcode]\[/url\])~ie";
$ameinfo['find'][] = "~(\[url=\"?$result[findcode]\"?\](.*?)\[/url\])~ie";
$ameinfo['replace'][] = 'ame_match("\1", "", ' . intval($result['extraction']) .', "' . ($result['embedregexp'] ? "~" . ame_slasher($result['embedregexp']) . "~sim" : "") . '", "' . ($result['validation'] ? "~" . ame_slasher($result['validation']) . "~sim" : "") . '",$ameinfo)';
$ameinfo['replace'][] = 'ame_match("\1", "\2", ' . intval($result['extraction']) .', "' . ($result['embedregexp'] ? "~" . ame_slasher($result['embedregexp']) . "~sim" : "") . '", "' . ($result['validation'] ? "~" . ame_slasher($result['validation']) . "~sim" : "") . '", $ameinfo)';
}
}
}
$inied = true;
}
$lastfind = $findonly;
return $ameinfo;
}
You can't put the replacement function in fetch_full_ameinfo(), because it needs to refer to the $param1 and $param2 variables, which are local to this function.
This means it needs to use eval() in the current function (this is essentially what preg_replace() does internally when it processes the /e flag).
You need to change the replacement string that fetch_full_ameinfo() creates so that it uses a variable instead of \1, \2, etc. to refer to the capture groups, because the callback function receives the captured matches as an array. So replace the block beginning with if (!$findonly) with this:
if (!$findonly)
{
$ameinfo['find'][] = "~($result[findcode])~i";
$ameinfo['replace'][] = 'ame_match_bbcode($param1, $param2, \'' . $result['ameid'] . '\', \'' . ame_slasher($result['title']) . '\', ' . $result['container'] . ', \'' . ame_slasher($result['replacecode']) . '\', \'$match[1]\', \'$match[2]\', \'$match[3]\', \'$match[4]\', \'$match[5]\', \'$match[6]\')';
}
else
{
$ameinfo['find'][] = "~(\[url\]$result[findcode]\[/url\])~i";
$ameinfo['find'][] = "~(\[url=\"?$result[findcode]\"?\](.*?)\[/url\])~i";
$ameinfo['replace'][] = 'ame_match("$match[1]", "", ' . intval($result['extraction']) .', "' . ($result['embedregexp'] ? "~" . ame_slasher($result['embedregexp']) . "~sim" : "") . '", "' . ($result['validation'] ? "~" . ame_slasher($result['validation']) . "~sim" : "") . '",$ameinfo)';
$ameinfo['replace'][] = 'ame_match("$match[1]", "$match[2]", ' . intval($result['extraction']) .', "' . ($result['embedregexp'] ? "~" . ame_slasher($result['embedregexp']) . "~sim" : "") . '", "' . ($result['validation'] ? "~" . ame_slasher($result['validation']) . "~sim" : "") . '", $ameinfo)';
}
Then change your code to:
$text = preg_replace_callback($ameinfo['find'], function($match) use (&$param1, &$param2, &$ameinfo) {
return eval($ameinfo['replace']);
}, ($param2 ? $param2 : $param1), 1);
I have error in line 2 and 13 in PHP 5.2, I have no idea to make the correction, I tried using create_function but not working, can anyone help with this?
function _process_special_keyword($str){
$callback = function($match){
$ret = $match[1] . '[' . $match[2] . ']';
if(!empty($match[3])){
$ret .= '.[' . $match[3] . ']';
}
$ret .= $match[4];
return $ret;
};
$strSQL = preg_replace_callback('/([\s\(\.,])(' . SPECIAL_KEYWORDS . ')(?:\.(' . SPECIAL_KEYWORDS . '))?([\s\)\.,])/i', $callback, $str);
$callback = function($match){
return 'CASE WHEN ' . $match[1] . ' THEN ' . $match[2] . ' ELSE ' . $match[3] . ' END';
};
$strSQL = preg_replace_callback('/if\s*\((.+),(.+),(.+)\)/i', $callback, $strSQL);
return $strSQL;
}
Thanks.
Error: Parse error: syntax error, unexpected T_FUNCTION
When using create_function(), the contents of the first argument should be a string representation of the PHP code that would fill the parentheses for the function declaration. The second argument should contain only the code inside the curly braces {} of the function declaration, the actual declaration itself should be omitted.
Try this code:
function _process_special_keyword($str){
$callback = create_function(
'$match',
'
$ret = $match[1] . "[" . $match[2] . "]";
if(!empty($match[3])){
$ret .= ".[" . $match[3] . "]";
}
$ret .= $match[4];
return $ret;
'
);
$strSQL = preg_replace_callback('/([\s\(\.,])(' . SPECIAL_KEYWORDS . ')(?:\.(' . SPECIAL_KEYWORDS . '))?([\s\)\.,])/i', $callback, $str);
$callback = create_function(
'$match',
'return "CASE WHEN " . $match[1] . " THEN " . $match[2] . " ELSE " . $match[3] . " END";'
);
$strSQL = preg_replace_callback('/if\s*\((.+),(.+),(.+)\)/i', $callback, $strSQL);
return $strSQL;
}
You can declare the callbacks outside of this function. Like this:
function _callback_one($match){
$ret = $match[1] . '[' . $match[2] . ']';
if(!empty($match[3])){
$ret .= '.[' . $match[3] . ']';
}
$ret .= $match[4];
return $ret;
}
function _callback_two($match){
return 'CASE WHEN ' . $match[1] . ' THEN ' . $match[2] . ' ELSE ' . $match[3] . ' END';
}
function _process_special_keyword($str){
$strSQL = preg_replace_callback('/([\s\(\.,])(' . SPECIAL_KEYWORDS . ')(?:\.(' . SPECIAL_KEYWORDS . '))?([\s\)\.,])/i', '_callback_one', $str);
$strSQL = preg_replace_callback('/if\s*\((.+),(.+),(.+)\)/i', '_callback_two', $strSQL);
return $strSQL;
}
Note: If these functions are in a class (meaning the function would be need to called like $this->_callback_one), pass an array as the "callback" parameter.
function _process_special_keyword($str){
$strSQL = preg_replace_callback('/([\s\(\.,])(' . SPECIAL_KEYWORDS . ')(?:\.(' . SPECIAL_KEYWORDS . '))?([\s\)\.,])/i', array($this, '_callback_one'), $str);
$strSQL = preg_replace_callback('/if\s*\((.+),(.+),(.+)\)/i', array($this, '_callback_two'), $strSQL);
return $strSQL;
}
according with object question, the faster way I think is something like so,
$f = <<<myfunc
\$ret = \$match[1] . '[' . \$match[2] . ']';
if(!empty(\$match[3])){
\$ret .= '.[' . \$match[3] . ']';
}
\$ret .= \$match[4];
return \$ret;
myfunc;
$callback = create_function('$match',$f);
note backslashes before $ and <<< FLAG FLAG; construct. In practice the answer of Rocket is more simple.
i have a function like this. i want reset the $output var first call.
function create_tree($tree_array, $reset = TRUE, $ul_class = FALSE) {
if($reset) unset($output); // NOT WORK!!!
static $output = '';
$class = '';
if ($ul_class) {
$class = ' class="' . $ul_class . '"';
}
$output .= '<ul' . $class . '>' . PHP_EOL;
foreach ($tree_array as $v) {
$output .= '<li>' . $v['name'] . '' . PHP_EOL;;
if (isset($v['children'])) {
create_tree($v['children'], false);
}
$output .= '</li>' . PHP_EOL;
}
$output .= '</ul>' . PHP_EOL;
return $output;
}
$output doesn't magically exist at that point in the function; it magically retains its value when the declaration is seen again.
if ($reset)
$output = '';