## Thursday, June 26, 2008

### SMS/Email Domains for U.S. Cellular Providers

I often see people asking how to send SMS messages from their website. Well, you can do so through your SMTP server or if you're using some other type of email system, for instance Postfix on Debian, you can use that too.

You send the message/email just like you would any other email, you just have to direct it to the address the service provider has setup to recieve messages.

In most cases this is the cellphones ten digit number @ provider-address dot com.
Below is a list of common U.S. service providers and the domain they have setup to recieve SMS messages via email protocols.

CarrierDomain Pattern
AirTouch Cellular 10digitphonenumber@airtouchpaging.com
Alltel 10digitphonenumber@alltelmessage.com
Ameritech Cellular 10digitphonenumber@paging.acswireless.com
AT&T Wireless 10digitphonenumber@mobile.att.net
Bell Atlantic 10digitphonenumber@message.bam.com
BellSouth 10digitphonenumber@wireless.bellsouth.com
Cellular One Not available from carrier
Cingular Wireless 10digitnumber@mobile.mywireless.com
Comcast Cellular 10digitphonenumber@cellularone.tstmsg.com
Nextel 10digitphonenumber@page.nextel.com
Omnipoint 10digitphonenumber@omnipointpcs.com
PrimeCo 10digitphonenumber@primeco.textmessage.com
Southwestern Bell 10digitphonenumber@email.swbw.com
Sprint 10digitphonenumber@messaging.sprintpcs.com
Suncom 10digitphonenumber@mobile.att.net
TMobile 10digitphonenumber@tmomail.net
Telecorp 10digitphonenumber@mobile.att.net
Tritel 10digitphonenumber@mobile.att.net
Triton PCS 10digitphonenumber@mobile.att.net
U.S. West 10digitphonenumber@uswestdatamail.com
Verizon 10digitphoneumber@msg.myvzw.com
Voicestream 10digitphonenumber@voicestream.net
Boost Mobile 10digitphonenumber@myboostmobile.com

Google is able to look these up just by having the number somehow, I'd really like to know where's they're getting it from.

### preg_replace_callback VS preg_replace

Some interesting results of a test between the preg_replace_callback function VS the preg_replace function using the e pattern modifier.

Here's the test code.
<?phpfunction uppers($match){ return strtoupper($match[0]);}$out = '12345678901234567890123456789012';$strs = array();$str_count = 1000;while($str_count){ $strs[] = md5($str_count . microtime()); $str_count--;}foreach($strs as &$str){$out = preg_replace('#[ace]+#e', 'strtoupper($0)',$str);}foreach($strs as &$str){ $out = preg_replace_callback('#[ace]+#', 'uppers',$str);}?>

The test was benchmarked using the profiler included in the Xdebug Debugger and Profiler Tool for PHP.
OS is Ubuntu 8.04, Apache version 2.2.8, PHP version 5.2.4
Profiler output is being viewed in KCachegrind.

Here's the callee map generated from the output.

And here's the slightly easier to understand source map.

The two numbers on the left are the percentage of the total runtime dedicated to the actions next to them.
It appears to me that the preg_replace_callback way is faster, but I would love to see how it performs on other OS's if anyone cares to do their own tests & comment.

## Sunday, June 22, 2008

### Unexpected '}' In Runtime-Created Function

When working the the create_function function in PHP, it's possible to get an error message similar to the following.

Parse error: syntax error, unexpected '}' in /var/www/test.php(36) : runtime-created function on line 1

Now if you're using the return from create_function in an anonymous context you might also get a message like the following.

Warning: preg_replace_callback() [function.preg-replace-callback]: Requires argument 2, '', to be a valid callback in /var/www/test.php on line 36

After getting a Parse Error in the beginning, a subsequent warning can be downright baffling since parse errors generally halt script execution. Apparently parse errors within anonymous, create_function context only halt execution within that context though.

Now when you look into that initial error and the create_function code portion thinking maybe you used a curly brace to end a function call instead of a closing parenthesis and don't see a curly brace anywhere "baffled" can't begin to explain the feeling you might have.

The reason for the initial error likely has to do with a missing semi-colon in the code argument of your create_function call. For instance if your code simply runs the arguments through a function like the following.

$str = preg_replace_callback('#[ACEGIKMOQSUWY]+#', create_function('$a', 'return strtolower($a[0])'),$str);

That seems perfectly fine, however it needs to have the semi-colon to end the function call as in the following.

$str = preg_replace_callback('#[ACEGIKMOQSUWY]+#', create_function('$a', 'return strtolower($a[0]);'),$str);

This fact can be extremely confusing if you've used preg_replace with the e modifier where this ending semi-colon isn't required.

Tip:

preg_replace_callback can be twice or more as fast as preg_replace and the e modifier.

## Friday, June 20, 2008

### Random Color Generation With Javascript

I'm sure there's quite a few ways to get a random color using JS, I can think of a few such as returning a random index from an array of CSS color names, or generating three random numbers between zero and 255 and formatting from there.

The following method is my favorite though because the single randomly generated integer can be easily converted into pretty much any other format or quickly returned as-is.
To illustrate this I've written the following function which will return a hexidecimal, RGB, or integer format random color depending on the argument passed to the function.

// @format (hex|rgb|null) : Format to return, default is integerfunction random_color(format){ var rint = Math.round(0xffffff * Math.random()); switch(format) {  case 'hex':   return ('#0' + rint.toString(16)).replace(/^#0([0-9a-f]{6})$/i, '#$1');  break;    case 'rgb':   return 'rgb(' + (rint >> 16) + ',' + (rint >> 8 & 255) + ',' + (rint & 255) + ')';  break;    default:   return rint;  break; }}

## Tuesday, June 17, 2008

### 50 Random PHP5 Facts

Here's a list of 50 49 random facts about PHP.

2. An iterator cannot be used with foreach by reference
3. Cannot create references to elements of a temporary array expression
4. Cannot create references to/from string offsets nor overloaded objects
5. Cannot assign by reference to overloaded objects
6. Only variable references should be returned by reference
7. Only variables can be passed by reference
8. Cannot return string offsets by reference
9. Cannot use string offset as an array
10. Cannot use object as array -- See Dans comment
11. Cannot use a NULL value as an array
12. Cannot use a scalar value as an array
13. foreach() can not iterate over objects without PHP class
14. Cannot use assign-op operators with overloaded objects nor string offsets
15. __HALT_COMPILER() can only be used from the outermost scope
16. Assigning the return value of new by reference is deprecated
17. Variables passed to each() must be an array or object
18. Constants may only evaluate to scalar values
19. is_a() is deprecated. The "instanceof" operator should be used instead This has changed as of PHP 5.3, see Gregs comment
20. Cannot add internal functions to return value from get_defined_functions()
21. Cannot add user functions to return value from get_defined_functions()
22. Static functions cannot be abstract
23. Exceptions must be derived from the Exception base class
24. Need to supply an object when throwing an exception
25. Cannot declare self-referencing constants
26. Cannot use call_user_function on objects without a class entry
27. Cannot access self:: when no class scope is active
28. Cannot access parent:: when no class scope is active
29. Cannot access parent:: when current class scope has no parent
30. add_assoc_function() is no longer supported
31. Usage of {} to access string offsets is deprecated and will be removed in PHP 6
32. Cannot re-assign $this 33. __toString() must not throw an exception 34. Can't use method return value in write context 35. Can't use function return value in write context 36. Multiple access type modifiers are not allowed 37. Cannot use the final modifier on an abstract class member 38. Default value for parameters with a class type hint can only be NULL 39. Default value for parameters with array type hint can only be an array or NULL 40. Cannot call __clone() method on objects - 'clone$obj' should be used instead
41. Clone method does not require arguments
42. Interfaces cannot not implement themselves
43. Classes may not inherit from classes declared final
44. Classes cannot inherit previously-inherited constants from interfaces
45. Classes cannot implement previously-implemented interfaces
46. Class declarations may not be nested
47. Cannot use reserved words as class or interface names
48. Interfaces may not include member variables
49. Properties cannot be declared abstract
50. Cannot declare properties final, the final modifier is allowed only for methods

## Wednesday, June 4, 2008

### Xdebug MUST be loaded as a Zend extension

XDebug profiler not working ?
Found this in your error log ?

PHP Warning: Xdebug MUST be loaded as a Zend extension ...

You've probably installed xdebug.so or php_xdebug.dll using a line similar to this in php.ini.

;extension=xdebug.so; or;extension=php_xdebug.dll

Well the fix seems to be simple, as seen in xdebugs installation instructions.

You need to use a different directive, and you need to specify the entire path to the so/dll.

Making Windows something similar to this
zend_extension_ts = "c:/php/modules/php_xdebug.dll"

And making UNIX/PECL something like this
zend_extension = "/usr/lib/php5/modules/xdebug.so"

I imagine the "_ts" corosponds to "Thread Safe" which could mean the "_ts" directive needs to be used on IIS, Apache2, & other multi-threaded servers, but I'm not entirely sure & haven't found any documentation on that yet.
So far the non-_ts version is working on my Apache2 test box, though.

Update: Using "zend_extension_ts" didn't work at all on my Debian/Apache2 box.

Now if you're using the new directive and still getting errors, which happen to come half-a-dozen at a time, in your logs, then you will want to add the directory used for extension_dir to the value of include_path in php.ini.

; Assuming the following;extension_dir = "/path/to/extensions";extension_dir = "c:\path\to\extensions"; UNIX: "/path1:/path2";include_path = ".:/usr/share/php:/path/to/extensions";; Windows: "\path1;\path2";include_path = ".;c:\php\includes;c:\path\to\extensions"