3

I downloaded the following code from a website for encoding GSM characters in SMS messages sned through their gateway.

Here's my test code:

$body = '£¥$@"\'.,;:_-=+*#%&<>?!¿¡§¤()ÄÖÑÜÉÅßÇÆΦΓΔΛΩΣΠΨΘØΞñüäòøàæåèéöùì{}[]|~^€';

$characters = array(
    'Δ'=>'0xD0', 'Φ'=>'0xDE', 'Γ'=>'0xAC', 'Λ'=>'0xC2',
    'Ω'=>'0xDB', 'Π'=>'0xBA', 'Ψ'=>'0xDD', 'Σ'=>'0xCA',
    'Θ'=>'0xD4', 'Ξ'=>'0xB1', '¡'=>'0xA1', '£'=>'0xA3',
    '¤'=>'0xA4', '¥'=>'0xA5', '§'=>'0xA7', '¿'=>'0xBF',
    'Ä'=>'0xC4', 'Å'=>'0xC5', 'Æ'=>'0xC6', 'Ç'=>'0xC7',
    'É'=>'0xC9', 'Ñ'=>'0xD1', 'Ö'=>'0xD6', 'Ø'=>'0xD8',
    'Ü'=>'0xDC', 'ß'=>'0xDF', 'à'=>'0xE0', 'ä'=>'0xE4',
    'å'=>'0xE5', 'æ'=>'0xE6', 'è'=>'0xE8', 'é'=>'0xE9',
    'ì'=>'0xEC', 'ñ'=>'0xF1', 'ò'=>'0xF2', 'ö'=>'0xF6',
    'ø'=>'0xF8', 'ù'=>'0xF9', 'ü'=>'0xFC',
);
$message = '';
if(mb_detect_encoding($body, 'UTF-8') != 'UTF-8') {
    $body = utf8_encode($body);
}
for ($i = 0; $i < mb_strlen($body, 'UTF-8'); $i++) {
    $c = mb_substr($body, $i, 1, 'UTF-8');
    if (isset($characters[$c])) {
        $message .= chr($characters[$c]);  //Line 53
    } else {
        $message .= $c;
    }
}

echo $message;

When I run the code in PHP 5.6 it correctly encodes the message for sending via SMS.

When I run in PHP 7 however, I received the following error and it does not work:

Notice: A non well formed numeric value encountered in /var/www/html/public/test.php on line 53

I notice in the docs for char() it accepts ASCII codes. Why is the current code working in PHP 5.6 and not 7 and what would be the best way to ensure it works in both versions?

Rizier123
  • 58,877
  • 16
  • 101
  • 156
Ben Sinclair
  • 3,896
  • 7
  • 54
  • 94
  • 3
    `chr()` expects an integer as argument. And you are passing a string containing a hex value. So you want to call first `hexdec()`, because as you see PHP 7 will now throw a notice, because it doesn't consider a hex string to be numeric anymore, see: http://php.net/manual/en/migration70.incompatible.php#migration70.incompatible.strings.hex – Rizier123 Sep 14 '16 at 00:49
  • 5
    Prior PHP 7 a hex string was considered to be numeric and thus casted to an integer in a numeric context. – Rizier123 Sep 14 '16 at 00:55
  • @Rizier123 `hexdec()` didn't work. But passing them through as a integer was the solution. Missed that! – Ben Sinclair Sep 14 '16 at 01:13

1 Answers1

5

Correct me if I'm wrong but encasing a hexidecimal value in quotes turns it into a String?

Basically, remove the single quotes from around the values e.g.

'Δ'=>'0xD0',

to

'Δ'=>0xD0,

Thus passing chr a valid integer

Edit: Just tested this theory and I seem to be correct:

<?php

var_dump('0xD0');
var_dump(0xD0);

Results in:

string(4) "0xD0"
int(208)

In the PHP manual chr takes 1 int value:

string chr ( int $ascii )
James Lockhart
  • 1,030
  • 11
  • 17