Convert preg_replace to preg_replace_callback with array inputs

I’m using a date converter PHP function which worked with preg_replace in PHP 5.x.

Now after the PHP 7.x update I can’t use the code due to error:

preg_replace(): The /e modifier is no longer supported, use preg_replace_callback instead.

The code is:

$pattern=array(
        "#Y#",//full year
        "#y#",//short year

        "#M#",//month short name
        "#F#",//month full name
        "#m#",//month number 0 lead
        "#n#",//month number
        "#t#",//days in month

        "#l#",//full week day
        "#D#",//short week day

        "#d#",//day number of month
        "#j#",//day number of month

        "#a#",//AM/PM short view
        "#A#",//AM/PM full view

        "#([^yYMmDdAa])#e"
        );
    $replace=array(
        $d->ENnum2FA($converted[0]),//year 13xx
        $d->ENnum2FA(substr($converted[0],2),true),//year xx lead zero

        $d->shmonths[$converted[1]],//month name
        $d->months[$converted[1]],//month name
        $d->ENnum2FA($converted[1],true), //month number
        $d->ENnum2FA($converted[1]), //month number
        //$converted[1],
        $d->j_days_in_month[$converted[1]],

        $d->days[strtolower(gmdate("D",$stamp))],//week day {full view}
        $d->ldays[strtolower(gmdate("D",$stamp))],//week day ‍‍{short view}

        $d->ENnum2FA($converted[2],true),//day of month
        $d->ENnum2FA($converted[2],true),//day of month

        $d->pmam[gmdate('a',$stamp)],
        $d->pmam[gmdate('A',$stamp)],

        "\$d->ENnum2FA(gmdate('\\1',\$stamp))"
        );

    $date= preg_replace($pattern,$replace,$format);

I used this link’s solution:

I made the following changes:

1. "#([^yYMmDdAa])#e" ===> "#([^yYMmDdAa])#

2. "\$d->ENnum2FA(gmdate('\\1',\$stamp))" ===> "\$d->ENnum2FA(gmdate('\$match[1]',\$stamp))"

3. $date= preg_replace($pattern,$replace,$format); ===> $date=preg_replace_callback($pattern, function($match) {
  return $replace;
}, $format);

Finally the code became:

$pattern=array(
		"#Y#",//full year
		"#y#",//short year
		
		"#M#",//month short name
		"#F#",//month full name
		"#m#",//month number 0 lead
		"#n#",//month number
		"#t#",//days in month
		
		"#l#",//full week day
		"#D#",//short week day
		
		"#d#",//day number of month
		"#j#",//day number of month

		"#a#",//AM/PM short view
		"#A#",//AM/PM full view
		
		"#([^yYMmDdAa])#"
		);
	$replace=array(
		$d->ENnum2FA($converted[0]),//year 13xx
		$d->ENnum2FA(substr($converted[0],2),true),//year xx lead zero
		
		$d->shmonths[$converted[1]],//month name
		$d->months[$converted[1]],//month name
		$d->ENnum2FA($converted[1],true), //month number
		$d->ENnum2FA($converted[1]), //month number
		//$converted[1],
		$d->j_days_in_month[$converted[1]],
		
		$d->days[strtolower(gmdate("D",$stamp))],//week day {full view}
		$d->ldays[strtolower(gmdate("D",$stamp))],//week day ‍‍{short view}

		$d->ENnum2FA($converted[2],true),//day of month
		$d->ENnum2FA($converted[2],true),//day of month

		$d->pmam[gmdate('a',$stamp)],
		$d->pmam[gmdate('A',$stamp)],
		
		"\$d->ENnum2FA(gmdate('\$match[1]',\$stamp))"
		);
$date=preg_replace_callback($pattern, function($match) {
  return $replace;
}, $format);

But nothing happens. I think it’s because of array inputs. How can I solve it?

You would actually need to use preg_replace_callback_array(), because there are different values/processing to do depending on what pattern is matched. The following should (untested) work (only includes the first two and the last pattern/function) -

// define an array consisting of the pattern (key) and call-back function (value) 
$pattern_function = [
	"#Y#" => function($m) use ($d, $converted, $stamp) { return $d->ENnum2FA($converted[0]); }, //full year
	"#y#" => function($m) use ($d, $converted, $stamp) { return $d->ENnum2FA(substr($converted[0],2),true); },//short year
	// ... you will need to fill in the rest of the pattern/functions
	"#([^yYMmDdAa])#" => function($m) use ($d, $converted, $stamp) { return $d->ENnum2FA(gmdate($m[1],$stamp)); }
	];

$date = preg_replace_callback_array($pattern_function, $format);

Also, the last pattern is probably supposed to include (which actually excludes) all the other characters that have their own pattern/function? For example, if a format character ‘j’ is used, the existing logic would result in both $d->ENnum2FA($converted[2],true) and $d->ENnum2FA(gmdate(‘j’, $stamp) being used.

Sponsor our Newsletter | Privacy Policy | Terms of Service