PageRenderTime 62ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 1ms

/text/src/test/resources/examples/php/pleac.in.php

https://github.com/rimolive/core
PHP | 5516 lines | 3126 code | 1103 blank | 1287 comment | 289 complexity | 2bff6f689da756c0f08fcd22fc63ef86 MD5 | raw file
Possible License(s): EPL-1.0, MPL-2.0-no-copyleft-exception

Large files files are truncated, but you can click here to view the full file

  1. # -*- php -*-
  2. # The examples are taken from the Perl Cookbook
  3. # By Tom Christiansen & Nathan Torkington
  4. # see http://www.oreilly.com/catalog/cookbook for more
  5. # @@PLEAC@@_NAME
  6. # @@SKIP@@ PHP
  7. # @@PLEAC@@_WEB
  8. # @@SKIP@@ http://php.net/
  9. # @@PLEAC@@_1.0
  10. #-----------------------------
  11. $string = '\n'; # two characters, \ and an n
  12. $string = 'Jon \'Maddog\' Orwant'; # literal single quotes
  13. $string = 'Jon "Maddog" Orwant'; # literal double quotes
  14. #-----------------------------
  15. $string = "\n"; # a "newline" character
  16. $string = "Jon \"Maddog\" Orwant"; # literal double quotes
  17. $string = "Jon 'Maddog' Orwant"; # literal single quotes
  18. #-----------------------------
  19. $a =
  20. "This is a multiline
  21. here document";
  22. $a = <<<EOF
  23. This is a multiline here document
  24. terminated by EOF on a line by itself
  25. EOF;
  26. #-----------------------------
  27. # @@PLEAC@@_1.1
  28. #-----------------------------
  29. $value = substr($string, $offset, $count);
  30. $value = substr($string, $offset);
  31. $string = substr_replace($string, $newstring, $offset, $count);
  32. $string = substr_replace($string, $newtail, $offset);
  33. #-----------------------------
  34. # get a 5-byte string, skip 3, then grab 2 8-byte strings, then the rest
  35. list($leading, $s1, $s2, $trailing) =
  36. array_values(unpack("A5a/x3/A8b/A8c/A*d", $data);
  37. # split at five byte boundaries
  38. preg_match_all ("/.{5}/", $data, $f, PREG_PATTERN_ORDER);
  39. $fivers = $f[0];
  40. # chop string into individual characters
  41. $chars = $string;
  42. #-----------------------------
  43. $string = "This is what you have";
  44. # +012345678901234567890 Indexing forwards (left to right)
  45. # 109876543210987654321- Indexing backwards (right to left)
  46. # note that 0 means 10 or 20, etc. above
  47. $first = substr($string, 0, 1); # "T"
  48. $start = substr($string, 5, 2); # "is"
  49. $rest = substr($string, 13); # "you have"
  50. $last = substr($string, -1); # "e"
  51. $end = substr($string, -4); # "have"
  52. $piece = substr($string, -8, 3); # "you"
  53. #-----------------------------
  54. $string = "This is what you have";
  55. print $string;
  56. #This is what you have
  57. $string = substr_replace($string, "wasn't", 5, 2); # change "is" to "wasn't"
  58. #This wasn't what you have
  59. $string = substr_replace($string, "ondrous", -12); # "This wasn't wondrous"
  60. #This wasn't wondrous
  61. $string = substr_replace($string, "", 0, 1); # delete first character
  62. #his wasn't wondrous
  63. $string = substr_replace($string, "", -10); # delete last 10 characters
  64. #his wasn'
  65. #-----------------------------
  66. if (preg_match("/pattern/", substr($string, -10)) {
  67. print "Pattern matches in last 10 characters\n";
  68. }
  69. # substitute "at" for "is", restricted to first five characters
  70. $string=(substr_replace(preg_replace("/is/", "at", substr($string,0,5)),0,5);
  71. #-----------------------------
  72. # exchange the first and last letters in a string
  73. $a = "make a hat";
  74. list($a[0], $a[strlen($a)-1]) = Array(substr($a,-1), substr($a,0,1));
  75. print $a;
  76. #-----------------------------
  77. # extract column with unpack
  78. $a = "To be or not to be";
  79. $b = unpack("x6/A6a", $a); # skip 6, grab 6
  80. print $b['a'];
  81. $b = unpack("x6/A2b/X5/A2c", $a); # forward 6, grab 2; backward 5, grab 2
  82. print $b['b']."\n".$b['c']."\n";
  83. #-----------------------------
  84. function cut2fmt() {
  85. $positions = func_get_args();
  86. $template = '';
  87. $lastpos = 1;
  88. foreach($positions as $place) {
  89. $template .= "A" . ($place - $lastpos) . " ";
  90. $lastpos = $place;
  91. }
  92. $template .= "A*";
  93. return $template;
  94. }
  95. $fmt = cut2fmt(8, 14, 20, 26, 30);
  96. print "$fmt\n";
  97. #A7 A6 A6 A6 A4 A*
  98. #-----------------------------
  99. # @@PLEAC@@_1.2
  100. #-----------------------------
  101. # use $b if $b is true, else $c
  102. $a = $b?$b:$c;
  103. # set $x to $y unless $x is already true
  104. $x || $x=$y;
  105. #-----------------------------
  106. # use $b if $b is defined, else $c
  107. $a = defined($b) ? $b : $c;
  108. #-----------------------------
  109. $foo = $bar || $foo = "DEFAULT VALUE";
  110. #-----------------------------
  111. $dir = array_shift($_SERVER['argv']) || $dir = "/tmp";
  112. #-----------------------------
  113. $dir = $_SERVER['argv'][0] || $dir = "/tmp";
  114. #-----------------------------
  115. $dir = defined($_SERVER['argv'][0]) ? array_shift($_SERVER['argv']) : "/tmp";
  116. #-----------------------------
  117. $dir = count($_SERVER['argv']) ? $_SERVER['argv'][0] : "/tmp";
  118. #-----------------------------
  119. $count[$shell?$shell:"/bin/sh"]++;
  120. #-----------------------------
  121. # find the user name on Unix systems
  122. $user = $_ENV['USER']
  123. || $user = $_ENV['LOGNAME']
  124. || $user = posix_getlogin()
  125. || $user = posix_getpwuid(posix_getuid())[0]
  126. || $user = "Unknown uid number $<";
  127. #-----------------------------
  128. $starting_point || $starting_point = "Greenwich";
  129. #-----------------------------
  130. count($a) || $a = $b; # copy only if empty
  131. $a = count($b) ? $b : $c; # assign @b if nonempty, else @c
  132. #-----------------------------
  133. # @@PLEAC@@_1.3
  134. #-----------------------------
  135. list($VAR1, $VAR2) = array($VAR2, $VAR1);
  136. #-----------------------------
  137. $temp = $a;
  138. $a = $b;
  139. $b = $temp;
  140. #-----------------------------
  141. $a = "alpha";
  142. $b = "omega";
  143. list($a, $b) = array($b, $a); # the first shall be last -- and versa vice
  144. #-----------------------------
  145. list($alpha, $beta, $production) = Array("January","March","August");
  146. # move beta to alpha,
  147. # move production to beta,
  148. # move alpha to production
  149. list($alpha, $beta, $production) = array($beta, $production, $alpha);
  150. #-----------------------------
  151. # @@PLEAC@@_1.4
  152. #-----------------------------
  153. $num = ord($char);
  154. $char = chr($num);
  155. #-----------------------------
  156. $char = sprintf("%c", $num); # slower than chr($num)
  157. printf("Number %d is character %c\n", $num, $num);
  158. #-----------------------------
  159. $ASCII = unpack("C*", $string);
  160. eval('$STRING = pack("C*", '.implode(',',$ASCII).');');
  161. #-----------------------------
  162. $ascii_value = ord("e"); # now 101
  163. $character = chr(101); # now "e"
  164. #-----------------------------
  165. printf("Number %d is character %c\n", 101, 101);
  166. #-----------------------------
  167. $ascii_character_numbers = unpack("C*", "sample");
  168. print explode(" ",$ascii_character_numbers)."\n";
  169. eval('$word = pack("C*", '.implode(',',$ascii_character_numbers).');');
  170. $word = pack("C*", 115, 97, 109, 112, 108, 101); # same
  171. print "$word\n";
  172. #-----------------------------
  173. $hal = "HAL";
  174. $ascii = unpack("C*", $hal);
  175. foreach ($ascii as $val) {
  176. $val++; # add one to each ASCII value
  177. }
  178. eval('$ibm = pack("C*", '.implode(',',$ascii).');');
  179. print "$ibm\n"; # prints "IBM"
  180. #-----------------------------
  181. # @@PLEAC@@_1.5
  182. #-----------------------------
  183. // using perl regexp
  184. $array = preg_split('//', $string ,-1, PREG_SPLIT_NO_EMPTY);
  185. // using PHP function: $array = str_split($string);
  186. // Cannot use unpack with a format of 'U*' in PHP.
  187. #-----------------------------
  188. for ($offset = 0; preg_match('/(.)/', $string, $matches, 0, $offset) > 0; $offset++) {
  189. // $matches[1] has charcter, ord($matches[1]) its number
  190. }
  191. #-----------------------------
  192. $seen = array();
  193. $string = "an apple a day";
  194. foreach (str_split($string) as $char) {
  195. $seen[$char] = 1;
  196. }
  197. $keys = array_keys($seen);
  198. sort($keys);
  199. print "unique chars are: " . implode('', $keys)) . "\n";
  200. unique chars are: adelnpy
  201. #-----------------------------
  202. $seen = array();
  203. $string = "an apple a day";
  204. for ($offset = 0; preg_match('/(.)/', $string, $matches, 0, $offset) > 0; $offset++) {
  205. $seen[$matches[1]] = 1;
  206. }
  207. $keys = array_keys($seen);
  208. sort($keys);
  209. print "unique chars are: " . implode('', $keys) . "\n";
  210. unique chars are: adelnpy
  211. #-----------------------------
  212. $sum = 0;
  213. foreach (unpack("C*", $string) as $byteval) {
  214. $sum += $byteval;
  215. }
  216. print "sum is $sum\n";
  217. // prints "1248" if $string was "an apple a day"
  218. #-----------------------------
  219. $sum = array_sum(unpack("C*", $string));
  220. #-----------------------------
  221. // sum - compute 16-bit checksum of all input files
  222. $handle = @fopen($argv[1], 'r');
  223. $checksum = 0;
  224. while (!feof($handle)) {
  225. $checksum += (array_sum(unpack("C*", fgets($handle))));
  226. }
  227. $checksum %= pow(2,16) - 1;
  228. print "$checksum\n";
  229. # @@INCLUDE@@ include/php/slowcat.php
  230. #-----------------------------
  231. # @@PLEAC@@_1.6
  232. #-----------------------------
  233. $revchars = strrev($string);
  234. #-----------------------------
  235. $revwords = implode(" ", array_reverse(explode(" ", $string)));
  236. #-----------------------------
  237. // reverse word order
  238. $string = 'Yoda said, "can you see this?"';
  239. $allwords = explode(" ", $string);
  240. $revwords = implode(" ", array_reverse($allwords));
  241. print $revwords . "\n";
  242. this?" see you "can said, Yoda
  243. #-----------------------------
  244. $revwords = implode(" ", array_reverse(explode(" ", $string)));
  245. #-----------------------------
  246. $revwords = implode(" ", array_reverse(preg_split("/(\s+)/", $string)));
  247. #-----------------------------
  248. $word = "reviver";
  249. $is_palindrome = ($word === strrev($word));
  250. #-----------------------------
  251. // quite a one-liner since "php" does not have a -n switch
  252. % php -r 'while (!feof(STDIN)) { $word = rtrim(fgets(STDIN)); if ($word == strrev($word) && strlen($word) > 5) print $word; }' < /usr/dict/words
  253. #-----------------------------
  254. # @@PLEAC@@_1.8
  255. #-----------------------------
  256. $text = preg_replace('/\$(\w+)/e', '$$1', $text);
  257. #-----------------------------
  258. list($rows, $cols) = Array(24, 80);
  259. $text = 'I am $rows high and $cols long';
  260. $text = preg_replace('/\$(\w+)/e', '$$1', $text);
  261. print $text;
  262. #-----------------------------
  263. $text = "I am 17 years old";
  264. $text = preg_replace('/(\d+)/e', '2*$1', $text);
  265. #-----------------------------
  266. # expand variables in $text, but put an error message in
  267. # if the variable isn't defined
  268. $text = preg_replace('/\$(\w+)/e','isset($$1)?$$1:\'[NO VARIABLE: $$1]\'', $text);
  269. #-----------------------------
  270. // As PHP arrays are used as hashes too, separation of section 4
  271. // and section 5 makes little sense.
  272. # @@PLEAC@@_1.9
  273. #-----------------------------
  274. $big = strtoupper($little);
  275. $little = strtolower($big);
  276. // PHP does not have the\L and\U string escapes.
  277. #-----------------------------
  278. $big = ucfirst($little);
  279. $little = strtolower(substr($big, 0, 1)) . substr($big, 1);
  280. #-----------------------------
  281. $beast = "dromedary";
  282. // capitalize various parts of $beast
  283. $capit = ucfirst($beast); // Dromedar
  284. // PHP does not have the\L and\U string escapes.
  285. $capall = strtoupper($beast); // DROMEDAR
  286. // PHP does not have the\L and\U string escapes.
  287. $caprest = strtolower(substr($beast, 0, 1)) . substr(strtoupper($beast), 1); // dROMEDAR
  288. // PHP does not have the\L and\U string escapes.
  289. #-----------------------------
  290. // titlecase each word's first character, lowercase the rest
  291. $text = "thIS is a loNG liNE";
  292. $text = ucwords(strtolower($text));
  293. print $text;
  294. This Is A Long Line
  295. #-----------------------------
  296. if (strtoupper($a) == strtoupper($b)) { // or strcasecmp($a, $b) == 0
  297. print "a and b are the same\n";
  298. }
  299. #-----------------------------
  300. # @@INCLUDE@@ include/php/randcap.php
  301. // % php randcap.php < genesis | head -9
  302. #-----------------------------
  303. # @@PLEAC@@_1.10
  304. #-----------------------------
  305. echo $var1 . func() . $var2; // scalar only
  306. #-----------------------------
  307. // PHP can only handle variable expression without operators
  308. $answer = "STRING ${[ VAR EXPR ]} MORE STRING";
  309. #-----------------------------
  310. $phrase = "I have " . ($n + 1) . " guanacos.";
  311. // PHP cannot handle the complex exression: ${\($n + 1)}
  312. #-----------------------------
  313. // Rest of Discussion is not applicable to PHP
  314. #-----------------------------
  315. // Interpolating functions not available in PHP
  316. #-----------------------------
  317. # @@PLEAC@@_1.11
  318. # @@INCOMPLETE@@
  319. # @@INCOMPLETE@@
  320. # @@PLEAC@@_1.12
  321. #-----------------------------
  322. $output = wordwrap($str, $width, $break, $cut);
  323. #-----------------------------
  324. # @@INCLUDE@@ include/php/wrapdemo.php
  325. #-----------------------------
  326. // merge multiple lines into one, then wrap one long line
  327. print wordwrap(str_replace("\n", " ", file_get_contents('php://stdin')));
  328. #-----------------------------
  329. while(!feof(STDIN)) {
  330. print wordwrap(str_replace("\n", " ", stream_get_line(STDIN, 0, "\n\n")));
  331. print "\n\n";
  332. }
  333. #-----------------------------
  334. # @@PLEAC@@_1.13
  335. #-----------------------------
  336. //backslash
  337. $var = preg_replace('/([CHARLIST])/', '\\\$1', $var);
  338. // double
  339. $var = preg_replace('/([CHARLIST])/', '$1$1', $var);
  340. #-----------------------------
  341. $var = preg_replace('/%/', '%%', $var);
  342. #-----------------------------
  343. $string = 'Mom said, "Don\'t do that."';
  344. $string = preg_replace('/([\'"])/', '\\\$1', $string);
  345. // in PHP you can also use the addslashes() function
  346. #-----------------------------
  347. $string = 'Mom said, "Don\'t do that."';
  348. $string = preg_replace('/([\'"])/', '$1$1', $string);
  349. #-----------------------------
  350. $string = preg_replace('/([^A-Z])/', '\\\$1', $string);
  351. #-----------------------------
  352. // PHP does not have the \Q and \E string metacharacters
  353. $string = "this is\\ a\\ test\\!";
  354. // PHP's quotemeta() function is not the same as perl's quotemeta() function
  355. $string = preg_replace('/(\W)/', '\\\$1', 'is a test!');
  356. #-----------------------------
  357. # @@PLEAC@@_1.14
  358. #-----------------------------
  359. $string = trim($string);
  360. #-----------------------------
  361. // print what's typed, but surrounded by > < symbols
  362. while (!feof(STDIN)) {
  363. print ">" . substr(fgets(STDIN), 0, -1) . "<\n";
  364. }
  365. #-----------------------------
  366. $string = preg_replace('/\s+/', ' ', $string); // finally, collapse middle
  367. #-----------------------------
  368. $string = trim($string);
  369. $string = preg_replace('/\s+/', ' ', $string);
  370. #-----------------------------
  371. // 1. trim leading and trailing white space
  372. // 2. collapse internal whitespace to single space each
  373. function sub_trim($string) {
  374. $string = trim($string);
  375. $string = preg_replace('/\s+/', ' ', $string);
  376. return $string;
  377. }
  378. #-----------------------------
  379. # @@PLEAC@@_1.15
  380. # @@INCOMPLETE@@
  381. # @@INCOMPLETE@@
  382. # @@PLEAC@@_1.16
  383. #-----------------------------
  384. $code = soundex($string);
  385. #-----------------------------
  386. $phoned_words = metaphone("Schwern");
  387. #-----------------------------
  388. // substitution function for getpwent():
  389. // returns an array of user entries,
  390. // each entry contains the username and the full name
  391. function getpwent() {
  392. $pwents = array();
  393. $handle = fopen("passwd", "r");
  394. while (!feof($handle)) {
  395. $line = fgets($handle);
  396. if (preg_match("/^#/", $line)) continue;
  397. $cols = explode(":", $line);
  398. $pwents[$cols[0]] = $cols[4];
  399. }
  400. return $pwents;
  401. }
  402. print "Lookup user: ";
  403. $user = rtrim(fgets(STDIN));
  404. if (empty($user)) exit;
  405. $name_code = soundex($user);
  406. $pwents = getpwent();
  407. foreach($pwents as $username => $fullname) {
  408. preg_match("/(\w+)[^,]*\b(\w+)/", $fullname, $matches);
  409. list(, $firstname, $lastname) = $matches;
  410. if ($name_code == soundex($username) ||
  411. $name_code == soundex($lastname) ||
  412. $name_code == soundex($firstname))
  413. {
  414. printf("%s: %s %s\n", $username, $firstname, $lastname);
  415. }
  416. }
  417. #-----------------------------
  418. # @@PLEAC@@_1.17
  419. #-----------------------------
  420. # @@INCLUDE@@ include/php/fixstyle.php
  421. #-----------------------------
  422. # @@INCLUDE@@ include/php/fixstyle2.php
  423. #-----------------------------
  424. // very fast, but whitespace collapse
  425. while (!feof($input)) {
  426. $i = 0;
  427. preg_match("/^(\s*)(.*)/", fgets($input), $matches); // emit leading whitespace
  428. fwrite($output, $matches[1]);
  429. foreach (preg_split("/(\s+)/", $matches[2]) as $token) { // preserve trailing whitespace
  430. fwrite($output, (array_key_exists($token, $config) ? $config[$token] : $token) . " ");
  431. }
  432. fwrite($output, "\n");
  433. }
  434. #-----------------------------
  435. // @@PLEAC@@_2.0
  436. // As is the case under so many other languages floating point use under PHP is fraught
  437. // with dangers. Although the basic techniques shown below are valid, please refer to
  438. // the official PHP documentation for known issues, bugs, and alternate approaches
  439. // @@PLEAC@@_2.1
  440. // Two basic approaches to numeric validation:
  441. // * Built-in functions like 'is_numeric', 'is_int', 'is_float' etc
  442. // * Regexes, as shown below
  443. $s = '12.345';
  444. preg_match('/\D/', $s) && die("has nondigits\n");
  445. preg_match('/^\d+$/', $s) || die("not a natural number\n");
  446. preg_match('/^-?\d+$/', $s) || die("not an integer\n");
  447. preg_match('/^[+-]?\d+$/', $s) || die("not an integer\n");
  448. preg_match('/^-?\d+\.?\d*$/', $s) || die("not a decimal\n");
  449. preg_match('/^-?(?:\d+(?:\.\d*)?|\.\d+)$/', $s) || die("not a decimal\n");
  450. preg_match('/^([+-]?)(?=\d|\.\d)\d*(\.\d*)?([Ee]([+-]?\d+))?$/', $s) || die("not a C float\n");
  451. // ----------------------------
  452. function getnum($s)
  453. {
  454. sscanf($s, "%D", $number); return isset($number) ? $number : 0;
  455. }
  456. echo getnum(123) . "\n"; // ok
  457. echo getnum(0xff) . "\n"; // ..
  458. echo getnum(044) . "\n"; // ..
  459. echo getnum('x') . "\n"; // fail
  460. // @@PLEAC@@_2.2
  461. // In PHP floating point comparisions are 'safe' [meaning the '==' comparison operator
  462. // can be used] as long as the value consists of 14 digits or less [total digits, either
  463. // side of the decimal point e.g. xxxxxxx.xxxxxxx, xxxxxxxxxxxxxx., .xxxxxxxxxxxxxx]. If
  464. // values with more digits must be compared, then:
  465. //
  466. // * Represent as strings, and take care to avoid any implicit conversions e.g. don't pass
  467. // a float as a float to a function and expect all digits to be retained - they won't be -
  468. // then use 'strcmp' to compare the strings
  469. //
  470. // * Avoid float use; perhaps use arbitrary precision arithmetic. In this case, the
  471. // 'bccomp' function is relevant
  472. // Will work as long as each floating point value is 14 digits or less
  473. if ($float_1 == $float_2)
  474. {
  475. ; // ...
  476. }
  477. // Compare as strings
  478. $cmp = strcmp('123456789.123456789123456789', '123456789.123456789123456788');
  479. // Use 'bccomp'
  480. $precision = 5; // Number of significant comparison digits after decimal point
  481. if (bccomp('1.111117', '1.111116', $precision))
  482. {
  483. ; // ...
  484. }
  485. $precision = 6;
  486. if (bccomp('1.111117', '1.111116', $precision))
  487. {
  488. ; // ...
  489. }
  490. // ----------------------------
  491. $wage = 536;
  492. $week = $wage * 40;
  493. printf("One week's wage is: $%.2f\n", $week / 100);
  494. // @@PLEAC@@_2.3
  495. // Preferred approach
  496. $rounded = round($unrounded, $precision);
  497. // Possible alternate approach
  498. $format = '%[width].[prec]f';
  499. $rounded = sprintf($format, $unrounded);
  500. // ------------
  501. $a = 0.255; $b = round($a, 2);
  502. echo "Unrounded: {$a}\nRounded: {$b}\n";
  503. $a = 0.255; $b = sprintf('%.2f', $a);
  504. echo "Unrounded: {$a}\nRounded: {$b}\n";
  505. $a = 0.255;
  506. printf("Unrounded: %.f\nRounded: %.2f\n", $a, $a);
  507. // ----------------------------
  508. echo "number\tint\tfloor\tceil\n";
  509. foreach(array(3.3, 3.5, 3.7, -3.3) as $number)
  510. {
  511. printf("%.1f\t%.1f\t%.1f\t%.1f\n", $number, (int) $number, floor($number), ceil($number));
  512. }
  513. // @@PLEAC@@_2.4
  514. // PHP offers the 'bindec' and 'decbin' functions to converting between binary and decimal
  515. $num = bindec('0110110');
  516. $binstr = decbin(54);
  517. // @@PLEAC@@_2.5
  518. foreach (range($X, $Y) as $i)
  519. {
  520. ; // ...
  521. }
  522. foreach (range($X, $Y, 7) as $i)
  523. {
  524. ; // ...
  525. }
  526. for ($i = $X; $i <= $Y; $i++)
  527. {
  528. ; // ...
  529. }
  530. for ($i = $X; $i <= $Y; $i += 7)
  531. {
  532. ; // ...
  533. }
  534. // ----------------------------
  535. echo 'Infancy is:'; foreach(range(0, 2) as $i) echo " {$i}\n";
  536. echo 'Toddling is:'; foreach(range(3, 4) as $i) echo " {$i}\n";
  537. echo 'Childhood is:'; foreach(range(5, 12) as $i) echo " {$i}\n";
  538. // @@PLEAC@@_2.6
  539. // PHP offers no native support for Roman Numerals. However, a 'Numbers_Roman' class
  540. // is available for download from PEAR: [http://pear.php.net/package/Numbers_Roman].
  541. // Note the following 'include' directives are required:
  542. //
  543. // include_once('Numbers/Roman.php');
  544. $roman = Numbers_Roman::toNumeral($arabic);
  545. $arabic = Numbers_Roman::toNumber($roman);
  546. // ----------------------------
  547. $roman_fifteen = Numbers_Roman::toNumeral(15);
  548. $arabic_fifteen = Numbers_Roman::toNumber($roman_fifteen);
  549. printf("Roman for fifteen is: %s\n", $roman_fifteen);
  550. printf("Arabic for fifteen is: %d\n", $arabic_fifteen);
  551. // @@PLEAC@@_2.7
  552. // Techniques used here simply mirror Perl examples, and are not an endorsement
  553. // of any particular RNG technique
  554. // In PHP do this ...
  555. $random = rand($lowerbound, $upperbound);
  556. $random = rand($x, $y);
  557. // ----------------------------
  558. function make_password($chars, $reqlen)
  559. {
  560. $len = strlen($chars);
  561. for ($i = 0; $i < $reqlen; $i++) $password .= substr($chars, rand(0, $len), 1);
  562. return $password;
  563. }
  564. $chars = 'ABCDEfghijKLMNOpqrstUVWXYz'; $reqlen = 8;
  565. $password = make_password($chars, $reqlen);
  566. // @@PLEAC@@_2.8
  567. // PHP sports a large number of C Standard Library routines including the 'srand'
  568. // function, used to re-seed the RNG used with calls to the 'rand' function. Thus,
  569. // as per Perl example:
  570. while (TRUE)
  571. {
  572. $seed = (int) fgets(STDIN);
  573. if (!empty($seed)) break;
  574. }
  575. srand($seed);
  576. // @@PLEAC@@_2.9
  577. // The above is considered - for many reasons - a poor way of seeding the RNG. PHP
  578. // also offers alternate versions of the functions, 'mt_srand' and 'mt_rand',
  579. // which are described as faster, and more 'random', though key to obtaining a
  580. // more 'random' distribution of generated numbers seems to be through using
  581. // a combination of a previously saved random value in combination with an
  582. // unrepeatable value [like the current time in microseconds] that is multiplied
  583. // by a large prime number, or perhaps as part of a hash [examples available in
  584. // PHP documentation for 'srand' and 'mt_srand']
  585. mt_srand($saved_random_value + microtime() * 1000003);
  586. // or
  587. mt_srand(($saved_random_value + hexdec(substr(md5(microtime()), -8))) & 0x7fffffff);
  588. // Use of 'mt_rand' together with an appropriate seeding approach should help better
  589. // approximate the generation of a 'truly random value'
  590. $truly_random_value = mt_rand();
  591. // @@PLEAC@@_2.10
  592. function random() { return (float) rand() / (float) getrandmax(); }
  593. function gaussian_rand()
  594. {
  595. $u1 = 0.0; $u2 = 0.0; $g1 = 0.0; $g2 = 0.0; $w = 0.0;
  596. do
  597. {
  598. $u1 = 2.0 * random() - 1.0; $u2 = 2.0 * random() - 1.0;
  599. $w = $u1 * $u1 + $u2 * $u2;
  600. } while ($w > 1.0);
  601. $w = sqrt((-2.0 * log($w)) / $w); $g2 = $u1 * $w; $g1 = $u2 * $w;
  602. return $g1;
  603. }
  604. // ------------
  605. $mean = 25.0; $sdev = 2.0;
  606. $salary = gaussian_rand() * $mean + $sdev;
  607. printf("You have been hired at: %.2f\n", $salary);
  608. // @@PLEAC@@_2.11
  609. // 'deg2rad' and 'rad2deg' are actually PHP built-ins, but here is how you might implement
  610. / them if needed
  611. function deg2rad_($deg) { return ($deg / 180.0) * M_PI; }
  612. function rad2deg_($rad) { return ($rad / M_PI) * 180.0; }
  613. // ------------
  614. printf("%f\n", deg2rad_(180.0));
  615. printf("%f\n", deg2rad(180.0));
  616. // ----------------------------
  617. function degree_sin($deg) { return sin(deg2rad($deg)); }
  618. // ------------
  619. $rad = deg2rad(380.0);
  620. printf("%f\n", sin($rad));
  621. printf("%f\n", degree_sin(380.0));
  622. // @@PLEAC@@_2.12
  623. function my_tan($theta) { return sin($theta) / cos($theta); }
  624. // ------------
  625. $theta = 3.7;
  626. printf("%f\n", my_tan($theta));
  627. printf("%f\n", tan($theta));
  628. // @@PLEAC@@_2.13
  629. $value = 100.0;
  630. $log_e = log($value);
  631. $log_10 = log10($value);
  632. // ----------------------------
  633. function log_base($base, $value) { return log($value) / log($base); }
  634. // ------------
  635. $answer = log_base(10.0, 10000.0);
  636. printf("log(10, 10,000) = %f\n", $answer);
  637. // @@PLEAC@@_2.14
  638. // PHP offers no native support for matrices. However, a 'Math_Matrix' class
  639. // is available for download from PEAR: [http://pear.php.net/package/Math_Matrix].
  640. // Note the following 'include' directives are required:
  641. //
  642. // include_once('Math/Matrix.php');
  643. $a = new Math_Matrix(array(array(3, 2, 3), array(5, 9, 8)));
  644. $b = new Math_Matrix(array(array(4, 7), array(9, 3), array(8, 1)));
  645. echo $a->toString() . "\n";
  646. echo $b->toString() . "\n";
  647. // NOTE: When I installed this package I had to rename the 'clone' method else
  648. // it would not load, so I chose to rename it to 'clone_', and this usage is
  649. // shown below. This bug may well be fixed by the time you obtain this package
  650. $c = $a->clone_();
  651. $c->multiply($b);
  652. echo $c->toString() . "\n";
  653. // @@PLEAC@@_2.15
  654. // PHP offers no native support for complex numbers. However, a 'Math_Complex' class
  655. // is available for download from PEAR: [http://pear.php.net/package/Math_Complex].
  656. // Note the following 'include' directives are required:
  657. //
  658. // include_once('Math/Complex.php');
  659. // include_once('Math/TrigOp.php');
  660. // include_once('Math/ComplexOp.php');
  661. $a = new Math_Complex(3, 5);
  662. $b = new Math_Complex(2, -2);
  663. $c = Math_ComplexOp::mult($a, $b);
  664. echo $c->toString() . "\n";
  665. // ----------------------------
  666. $d = new Math_Complex(3, 4);
  667. $r = Math_ComplexOp::sqrt($d);
  668. echo $r->toString() . "\n";
  669. // @@PLEAC@@_2.16
  670. // Like C, PHP supports decimal-alternate notations. Thus, for example, the integer
  671. // value, 867, is expressable in literal form as:
  672. //
  673. // Hexadecimal -> 0x363
  674. // Octal -> 01543
  675. //
  676. // For effecting such conversions using strings there is 'sprintf' and 'sscanf'.
  677. $dec = 867;
  678. $hex = sprintf('%x', $dec);
  679. $oct = sprintf('%o', $dec);
  680. // ------------
  681. $dec = 0;
  682. $hex = '363';
  683. sscanf($hex, '%x', $dec);
  684. // ------------
  685. $dec = 0;
  686. $oct = '1543';
  687. sscanf($oct, '%o', $dec);
  688. // ----------------------------
  689. $number = 0;
  690. printf('Gimme a number in decimal, octal, or hex: ');
  691. sscanf(fgets(STDIN), '%D', $number);
  692. printf("%d %x %o\n", $number, $number, $number);
  693. // @@PLEAC@@_2.17
  694. // PHP offers the 'number_format' built-in function to, among many other format tasks,
  695. // commify numbers. Perl-compatible [as well as extended] regexes are also available
  696. function commify_series($s) { return number_format($s, 0, '', ','); }
  697. // ------------
  698. $hits = 3456789;
  699. printf("Your website received %s accesses last month\n", commify_series($hits));
  700. // ----------------------------
  701. function commify($s)
  702. {
  703. return strrev(preg_replace('/(\d\d\d)(?=\d)(?!\d*\.)/', '${1},', strrev($s)));
  704. }
  705. // ------------
  706. $hits = 3456789;
  707. echo commify(sprintf("Your website received %d accesses last month\n", $hits));
  708. // @@PLEAC@@_2.18
  709. function pluralise($value, $root, $singular='' , $plural='s')
  710. {
  711. return $root . (($value > 1) ? $plural : $singular);
  712. }
  713. // ------------
  714. $duration = 1;
  715. printf("It took %d %s\n", $duration, pluralise($duration, 'hour'));
  716. printf("%d %s %s enough.\n", $duration, pluralise($duration, 'hour'),
  717. pluralise($duration, '', 'is', 'are'));
  718. $duration = 5;
  719. printf("It took %d %s\n", $duration, pluralise($duration, 'hour'));
  720. printf("%d %s %s enough.\n", $duration, pluralise($duration, 'hour'),
  721. pluralise($duration, '', 'is', 'are'));
  722. // ----------------------------
  723. function plural($singular)
  724. {
  725. $s2p = array('/ss$/' => 'sses', '/([psc]h)$/' => '${1}es', '/z$/' => 'zes',
  726. '/ff$/' => 'ffs', '/f$/' => 'ves', '/ey$/' => 'eys',
  727. '/y$/' => 'ies', '/ix$/' => 'ices', '/([sx])$/' => '$1es',
  728. '$' => 's');
  729. foreach($s2p as $s => $p)
  730. {
  731. if (preg_match($s, $singular)) return preg_replace($s, $p, $singular);
  732. }
  733. }
  734. // ------------
  735. foreach(array('mess', 'index', 'leaf', 'puppy') as $word)
  736. {
  737. printf("%6s -> %s\n", $word, plural($word));
  738. }
  739. // @@PLEAC@@_2.19
  740. // @@INCOMPLETE@@
  741. // @@INCOMPLETE@@
  742. // @@PLEAC@@_3.0
  743. // PHP's date / time suport is quite extensive, and appears grouped into three areas of
  744. // functionality:
  745. //
  746. // * UNIX / C Library [libc]-based routines, which include [among others]:
  747. // - localtime, gmtime
  748. // - strftime, strptime, mktime
  749. // - time, getdate, gettimeofday,
  750. //
  751. // * PHP 'native' functions, those date / time routines released in earlier versions,
  752. // and which otherwise provide 'convenience' functionality; these include:
  753. // - date
  754. // - strtotime
  755. //
  756. // * 'DateTime' class-based. This facility appears [according to the PHP documentation]
  757. // to be extremely new / experimental, so whilst usage examples will be provided, they
  758. // should not be taken to be 'official' examples, and obviously, subject to change.
  759. // My own impression is that this facility is currently only partially implemented,
  760. // so there is limited use for these functions. The functions included in this group
  761. // are some of the 'date_'-prefixed functions; they are, however, not used standalone,
  762. // but as methods in conjunction with an object. Typical usage:
  763. //
  764. // $today = new DateTime(); // actually calls: date_create($today, ...);
  765. // echo $today->format('U') . "\n"; // actually calls: date_format($today, ...);
  766. //
  767. // Also worth mentioning is the PEAR [PHP Extension and Repository] package, 'Calendar',
  768. // which offers a rich set of date / time manipulation facilities. However, since it is
  769. // not currently shipped with PHP, no examples appear
  770. // Helper functions for performing date arithmetic
  771. function dateOffset()
  772. {
  773. static $tbl = array('sec' => 1, 'min' => 60, 'hou' => 3600, 'day' => 86400, 'wee' => 604800);
  774. $delta = 0;
  775. foreach (func_get_args() as $arg)
  776. {
  777. $kv = explode('=', $arg);
  778. $delta += $kv[1] * $tbl[strtolower(substr($kv[0], 0, 3))];
  779. }
  780. return $delta;
  781. }
  782. function dateInterval($intvltype, $timevalue)
  783. {
  784. static $tbl = array('sec' => 1, 'min' => 60, 'hou' => 3600, 'day' => 86400, 'wee' => 604800);
  785. return (int) round($timevalue / $tbl[strtolower(substr($intvltype, 0, 3))]);
  786. }
  787. // ----------------------------
  788. // Extract indexed array from 'getdate'
  789. $today = getdate();
  790. printf("Today is day %d of the current year\n", $today['yday']);
  791. // Extract indexed, and associative arrays, respectively, from 'localtime'
  792. $today = localtime();
  793. printf("Today is day %d of the current year\n", $today[7]);
  794. $today = localtime(time(), TRUE);
  795. printf("Today is day %d of the current year\n", $today['tm_yday']);
  796. // @@PLEAC@@_3.1
  797. define(SEP, '-');
  798. // ------------
  799. $today = getdate();
  800. $day = $today['mday'];
  801. $month = $today['mon'];
  802. $year = $today['year'];
  803. // Either do this to use interpolation:
  804. $sep = SEP;
  805. echo "Current date is: {$year}{$sep}{$month}{$sep}{$day}\n";
  806. // or simply concatenate:
  807. echo 'Current date is: ' . $year . SEP . $month . SEP . $day . "\n";
  808. // ------------
  809. $today = localtime(time(), TRUE);
  810. $day = $today['tm_mday'];
  811. $month = $today['tm_mon'] + 1;
  812. $year = $today['tm_year'] + 1900;
  813. printf("Current date is: %4d%s%2d%s%2d\n", $year, SEP, $month, SEP, $day);
  814. // ------------
  815. $format = 'Y' . SEP . 'n' . SEP . 'd';
  816. $today = date($format);
  817. echo "Current date is: {$today}\n";
  818. // ------------
  819. $sep = SEP;
  820. $today = strftime("%Y$sep%m$sep%d");
  821. echo "Current date is: {$today}\n";
  822. // @@PLEAC@@_3.2
  823. $timestamp = mktime($hour, $min, $sec, $month, $day, $year);
  824. $timestamp = gmmktime($hour, $min, $sec, $month, $day, $year);
  825. // @@PLEAC@@_3.3
  826. $dmyhms = getdate(); // timestamp: current date / time
  827. $dmyhms = getdate($timestamp); // timestamp: arbitrary
  828. $day = $dmyhms['mday'];
  829. $month = $dmyhms['mon'];
  830. $year = $dmyhms['year'];
  831. $hours = $dmyhms['hours'];
  832. $minutes = $dmyhms['minutes'];
  833. $seconds = $dmyhms['seconds'];
  834. // @@PLEAC@@_3.4
  835. // Date arithmetic is probably most easily performed using timestamps [i.e. *NIX Epoch
  836. // Seconds]. Dates - in whatever form - are converted to timestamps, these are
  837. // arithmetically manipulated, and the result converted to whatever form required.
  838. // Note: use 'mktime' to create timestamps properly adjusted for daylight saving; whilst
  839. // 'strtotime' is more convenient to use, it does not, AFAIK, include this adjustment
  840. $when = $now + $difference;
  841. $then = $now - $difference;
  842. // ------------
  843. $now = mktime(0, 0, 0, 8, 6, 2003);
  844. $diff1 = dateOffset('day=1'); $diff2 = dateOffset('weeks=2');
  845. echo 'Today is: ' . date('Y-m-d', $now) . "\n";
  846. echo 'One day in the future is: ' . date('Y-m-d', $now + $diff1) . "\n";
  847. echo 'Two weeks in the past is: ' . date('Y-m-d', $now - $diff2) . "\n";
  848. // ----------------------------
  849. // Date arithmetic performed using a custom function, 'dateOffset'. Internally, offset may
  850. // be computed in one of several ways:
  851. // * Direct timestamp manipulation - fastest, but no daylight saving adjustment
  852. // * Via 'date' built-in function - slower [?], needs a base time from which to
  853. // compute values, but has daylight saving adjustment
  854. // * Via 'strtotime' built-in function - as for 'date'
  855. // * Via 'DateTime' class
  856. //
  857. // Approach used here is to utilise direct timestamp manipulation in 'dateOffset' [it's
  858. // performance can also be improved by replacing $tbl with a global definition etc],
  859. // and to illustrate how the other approaches might be used
  860. // 1. 'dateOffset'
  861. $birthtime = mktime(3, 45, 50, 1, 18, 1973);
  862. $interval = dateOffset('day=55', 'hours=2', 'min=17', 'sec=5');
  863. $then = $birthtime + $interval;
  864. printf("Birthtime is: %s\nthen is: %s\n", date(DATE_RFC1123, $birthtime), date(DATE_RFC1123, $then));
  865. // ------------
  866. // 2. 'date'
  867. // Base values, and offsets, respectively
  868. $hr = 3; $min = 45; $sec = 50; $mon = 1; $day = 18; $year = 1973;
  869. $yroff = 0; $monoff = 0; $dayoff = 55; $hroff = 2; $minoff = 17; $secoff = 5;
  870. // Base date
  871. $birthtime = mktime($hr, $min, $sec, $mon, $day, $year, TRUE);
  872. $year = date('Y', $birthtime) + $yroff;
  873. $mon = date('m', $birthtime) + $monoff;
  874. $day = date('d', $birthtime) + $dayoff;
  875. $hr = date('H', $birthtime) + $hroff;
  876. $min = date('i', $birthtime) + $minoff;
  877. $sec = date('s', $birthtime) + $secoff;
  878. // Offset date
  879. $then = mktime($hr, $min, $sec, $mon, $day, $year, TRUE);
  880. printf("Birthtime is: %s\nthen is: %s\n", date(DATE_RFC1123, $birthtime), date(DATE_RFC1123, $then));
  881. // ------------
  882. // 3. 'strtotime'
  883. // Generate timestamp whatever way is preferable
  884. $birthtime = mktime(3, 45, 50, 1, 18, 1973);
  885. $birthtime = strtotime('1/18/1973 03:45:50');
  886. $then = strtotime('+55 days 2 hours 17 minutes 2 seconds', $birthtime);
  887. printf("Birthtime is: %s\nthen is: %s\n", date(DATE_RFC1123, $birthtime), date(DATE_RFC1123, $then));
  888. // ------------
  889. // 4. 'DateTime' class
  890. $birthtime = new DateTime('1/18/1973 03:45:50');
  891. $then = new DateTime('1/18/1973 03:45:50');
  892. $then->modify('+55 days 2 hours 17 minutes 2 seconds');
  893. printf("Birthtime is: %s\nthen is: %s\n", $birthtime->format(DATE_RFC1123), $then->format(DATE_RFC1123));
  894. // @@PLEAC@@_3.5
  895. // Date intervals are most easily computed using timestamps [i.e. *NIX Epoch
  896. // Seconds] which, of course, gives the interval result is seconds from which
  897. // all other interval measures [days, weeks, months, years] may be derived.
  898. // Refer to previous section for discussion of daylight saving and other related
  899. // problems
  900. $interval_seconds = $recent - $earlier;
  901. // ----------------------------
  902. // Conventional approach ...
  903. $bree = strtotime('16 Jun 1981, 4:35:25');
  904. $nat = strtotime('18 Jan 1973, 3:45:50');
  905. // ... or, with daylight saving adjustment
  906. $bree = mktime(4, 35, 25, 6, 16, 1981, TRUE);
  907. $nat = mktime(3, 45, 50, 1, 18, 1973, TRUE);
  908. $difference = $bree - $nat;
  909. // 'dateInterval' custom function computes intervals in several measures given an
  910. // interval in seconds. Note, 'month' and 'year' measures not provided
  911. printf("There were %d seconds between Nat and Bree\n", $difference);
  912. printf("There were %d weeks between Nat and Bree\n", dateInterval('weeks', $difference));
  913. printf("There were %d days between Nat and Bree\n", dateInterval('days', $difference));
  914. printf("There were %d hours between Nat and Bree\n", dateInterval('hours', $difference));
  915. printf("There were %d minutes between Nat and Bree\n", dateInterval('mins', $difference));
  916. // @@PLEAC@@_3.6
  917. // 'getdate' accepts a timestamp [or implicitly calls 'time'] and returns an array of
  918. // date components. It returns much the same information as 'strptime' except that
  919. // the component names are different
  920. $today = getdate();
  921. $weekday = $today['wday'];
  922. $monthday = $today['mday'];
  923. $yearday = $today['yday'];
  924. $weeknumber = (int) round($yearday / 7.0);
  925. // Safter method of obtaining week number
  926. $weeknumber = strftime('%U') + 1;
  927. // ----------------------------
  928. define(SEP, '/');
  929. $day = 16;
  930. $month = 6;
  931. $year = 1981;
  932. $timestamp = mktime(0, 0, 0, $month, $day, $year);
  933. $date = getdate($timestamp);
  934. $weekday = $date['wday'];
  935. $monthday = $date['mday'];
  936. $yearday = $date['yday'];
  937. $weeknumber = (int) round($yearday / 7.0);
  938. $weeknumber = strftime('%U', $timestamp) + 1;
  939. // Interpolate ...
  940. $sep = SEP;
  941. echo "{$month}{$sep}{$day}{$sep}{$year} was a {$date['weekday']} in week {$weeknumber}\n";
  942. // ... or, concatenate
  943. echo $month . SEP . $day . SEP . $year . ' was a ' . $date['weekday']
  944. . ' in week ' . $weeknumber . "\n";
  945. // @@PLEAC@@_3.7
  946. // 'strtotime' parses a textual date expression by attempting a 'best guess' at
  947. // the format, and either fails, or generates a timestamp. Timestamp could be fed
  948. // into any one of the various functions; example:
  949. $timestamp = strtotime('1998-06-03'); echo strftime('%Y-%m-%d', $timestamp) . "\n";
  950. // 'strptime' parses a textual date expression according to a specified format,
  951. // and returns an array of date components; components can be easily dumped
  952. print_r(strptime('1998-06-03', '%Y-%m-%d'));
  953. // ----------------------------
  954. // Parse date string according to format
  955. $darr = strptime('1998-06-03', '%Y-%m-%d');
  956. if (!empty($darr))
  957. {
  958. // Show date components in 'debug' form
  959. print_r($darr);
  960. // Check whether there was a parse error i.e. one or more components could not
  961. // be extracted from the string
  962. if (empty($darr['unparsed']))
  963. {
  964. // Properly parsed date, so validate required components using, 'checkdate'
  965. if (checkdate($darr['tm_mon'] + 1, $darr['tm_mday'], $darr['tm_year'] + 1900))
  966. echo "Parsed date verified as correct\n";
  967. else
  968. echo "Parsed date failed verification\n";
  969. }
  970. else
  971. {
  972. echo "Date string parse not complete; failed components: {$darr['unparsed']}\n";
  973. }
  974. }
  975. else
  976. {
  977. echo "Date string could not be parsed\n";
  978. }
  979. // @@PLEAC@@_3.8
  980. // 'date' and 'strftime' both print a date string based on:
  981. // * Format String, describing layout of date components
  982. // * Timestamp [*NIX Epoch Seconds], either given explicitly, or implictly
  983. // via a call to 'time' which retrieves current time value
  984. $ts = 1234567890;
  985. date('Y/m/d', $ts);
  986. date('Y/m/d', mktime($h, $m, $s, $mth, $d, $y, $is_dst));
  987. date('Y/m/d'); // same as: date('Y/m/d', time());
  988. // ------------
  989. $ts = 1234567890;
  990. strftime('%Y/%m/%d', $ts);
  991. strftime('%Y/%m/%d', mktime($h, $m, $s, $mth, $d, $y, $is_dst));
  992. strftime('%Y/%m/%d'); // same as: strftime('%Y/%m/%d', time());
  993. // ----------------------------
  994. // 'mktime' creates a local time timestamp
  995. $t = strftime('%a %b %e %H:%M:%S %z %Y', mktime(3, 45, 50, 1, 18, 73, TRUE));
  996. echo "{$t}\n";
  997. // 'gmmktime' creates a GMT time timestamp
  998. $t = strftime('%a %b %e %H:%M:%S %z %Y', gmmktime(3, 45, 50, 1, 18, 73));
  999. echo "{$t}\n";
  1000. // ----------------------------
  1001. // 'strtotime' parses a textual date expression, and generates a timestamp
  1002. $t = strftime('%A %D', strtotime('18 Jan 1973, 3:45:50'));
  1003. echo "{$t}\n";
  1004. // This should generate output identical to previous example
  1005. $t = strftime('%A %D', mktime(3, 45, 50, 1, 18, 73, TRUE));
  1006. echo "{$t}\n";
  1007. // @@PLEAC@@_3.9
  1008. // PHP 5 and above can use the built-in, 'microtime'. Crude implementation for ealier versions:
  1009. // function microtime() { $t = gettimeofday(); return (float) ($t['sec'] + $t['usec'] / 1000000.0); }
  1010. // ------------
  1011. $before = microtime();
  1012. $line = fgets(STDIN);
  1013. $elapsed = microtime() - $before;
  1014. printf("You took %.3f seconds\n", $elapsed);
  1015. // ------------
  1016. define(NUMBER_OF_TIMES, 100);
  1017. define(SIZE, 500);
  1018. for($i = 0; $i < NUMBER_OF_TIMES; $i++)
  1019. {
  1020. $arr = array();
  1021. for($j = 0; $j < SIZE; $j++) $arr[] = rand();
  1022. $begin = microtime();
  1023. sort($arr);
  1024. $elapsed = microtime() - $begin;
  1025. $total_time += $elapsed;
  1026. }
  1027. printf("On average, sorting %d random numbers takes %.5f seconds\n", SIZE, $total_time / (float) NUMBER_OF_TIMES);
  1028. // @@PLEAC@@_3.10
  1029. // Low-resolution: sleep time specified in seconds
  1030. sleep(1);
  1031. // High-resolution: sleep time specified in microseconds [not reliable under Windows]
  1032. usleep(250000);
  1033. // @@PLEAC@@_3.11
  1034. // @@INCOMPLETE@@
  1035. // @@INCOMPLETE@@
  1036. // @@PLEAC@@_4.0
  1037. // Nested arrays are supported, and may be easily printed using 'print_r'
  1038. $nested = array('this', 'that', 'the', 'other');
  1039. $nested = array('this', 'that', array('the', 'other')); print_r($nested);
  1040. $tune = array('The', 'Star-Spangled', 'Banner');
  1041. // @@PLEAC@@_4.1
  1042. // PHP offers only the 'array' type which is actually an associative array, though
  1043. // may be numerically indexed, to mimic vectors and matrices; there is no separate
  1044. // 'list' type
  1045. $a = array('quick', 'brown', 'fox');
  1046. // ------------
  1047. $a = escapeshellarg('Why are you teasing me?');
  1048. // ------------
  1049. $lines = <<<END_OF_HERE_DOC
  1050. The boy stood on the burning deck,
  1051. it was as hot as glass.
  1052. END_OF_HERE_DOC;
  1053. // ------------
  1054. $bigarray = array_map('rtrim', file('mydatafile'));
  1055. // ------------
  1056. $banner = 'The mines of Moria';
  1057. $banner = escapeshellarg('The mines of Moria');
  1058. // ------------
  1059. $name = 'Gandalf';
  1060. $banner = "Speak {$name}, and enter!";
  1061. $banner = 'Speak ' . escapeshellarg($name) . ' and welcome!';
  1062. // ------------
  1063. $his_host = 'www.perl.com';
  1064. $host_info = `nslookup $his_host`;
  1065. $cmd = 'ps ' . posix_getpid(); $perl_info = `$cmd`;
  1066. $shell_info = `ps $$`;
  1067. // ------------
  1068. $banner = array('Costs', 'only', '$4.95');
  1069. $banner = array_map('escapeshellarg', split(' ', 'Costs only $4.95'));
  1070. // ------------
  1071. // AFAIK PHP doesn't support non-quoted strings ala Perl's 'q', 'qq' and 'qw', so arrays
  1072. // created from strings must use quoted strings, and make use of 'split' [or equivalent].
  1073. // A slew of functions exist for performing string quoting, including 'escapeshellarg',
  1074. // 'quotemeta', and 'preg_quote'
  1075. $brax = split(' ', '( ) < > { } [ ]');
  1076. // Do this to quote each element within '..'
  1077. // $brax = array_map('escapeshellarg', split(' ', '( ) < > { } [ ]'));
  1078. $rings = split(' ', 'Nenya Narya Vilya');
  1079. $tags = split(' ', 'LI TABLE TR TD A IMG H1 P');
  1080. $sample = split(' ', 'The vertical bar | looks and behaves like a pipe.');
  1081. // @@PLEAC@@_4.2
  1082. function commify_series($list)
  1083. {
  1084. $n = str_word_count($list); $series = str_word_count($list, 1);
  1085. if ($n == 0) return NULL;
  1086. if ($n == 1) return $series[0];
  1087. if ($n == 2) return $series[0] . ' and ' . $series[1];
  1088. return join(', ', array_slice($series, 0, -1)) . ', and ' . $series[$n - 1];
  1089. }
  1090. // ------------
  1091. echo commify_series('red') . "\n";
  1092. echo commify_series('red yellow') . "\n";
  1093. echo commify_series('red yellow green') . "\n";
  1094. $mylist = 'red yellow green';
  1095. echo 'I have ' . commify_series($mylist) . " marbles.\n";
  1096. // ----------------------------
  1097. function commify_series($arr)
  1098. {
  1099. $n = count($arr); $sepchar = ',';
  1100. foreach($arr as $str)
  1101. {
  1102. if (strpos($str, ',') === false) continue;
  1103. $sepchar = ';'; break;
  1104. }
  1105. if ($n == 0) return NULL;
  1106. if ($n == 1) return $arr[0];
  1107. if ($n == 2) return $arr[0] . ' and ' . $arr[1];
  1108. return join("{$sepchar} ", array_slice($arr, 0, -1)) . "{$sepchar} and " . $arr[$n - 1];
  1109. }
  1110. // ------------
  1111. $lists = array(
  1112. array('just one thing'),
  1113. split(' ', 'Mutt Jeff'),
  1114. split(' ', 'Peter Paul Mary'),
  1115. array('To our parents', 'Mother Theresa', 'God'),
  1116. array('pastrami', 'ham and cheese', 'peanut butter and jelly', 'tuna'),
  1117. array('recycle tired, old phrases', 'ponder big, happy thoughts'),
  1118. array('recycle tired, old phrases', 'ponder big, happy thoughts', 'sleep and dream peacefully'));
  1119. foreach($lists as $arr)
  1120. {
  1121. echo 'The list is: ' . commify_series($arr) . ".\n";
  1122. }
  1123. // @@PLEAC@@_4.3
  1124. // AFAICT you cannot grow / shrink an array to an arbitrary size. However, you can:
  1125. // * Grow an array by appending an element using subscrip notation, or using
  1126. // either 'array_unshift' or 'array_push' to add one or more elements
  1127. $arr[] = 'one';
  1128. array_unshift($arr, 'one', 'two', 'three');
  1129. array_push($arr, 'one', 'two', 'three');
  1130. // * Shrink an array by using 'unset' to remove one or more specific elements, or
  1131. // either 'array_shift' or 'array_pop' to remove an element from the ends
  1132. unset($arr[$idx1], $arr[$idx2], $arr[$idx3]);
  1133. $item = array_shift($arr);
  1134. $item = array_pop($arr);
  1135. // ----------------------------
  1136. function what_about_the_array()
  1137. {
  1138. global $people;
  1139. echo 'The array now has ' . count($people) . " elements\n";
  1140. echo 'The index value of the last element is ' . (count($people) - 1) . "\n";
  1141. echo 'Element #3 is ' . $people[3] . "\n";
  1142. }
  1143. $people = array('Crosby', 'Stills', 'Nash', 'Young');
  1144. what_about_the_array();
  1145. array_pop($people);
  1146. what_about_the_array();
  1147. // Cannot, AFAICT, resize the array to an arbitrary size
  1148. # @@PLEAC@@_4.4
  1149. foreach ($list as $item) {
  1150. // do something with $item
  1151. }
  1152. // Environment listing example
  1153. // PHP defines a superglobal $_ENV to provide access to environment
  1154. // variables.
  1155. // Beware, array assignment means copying in PHP. You need to use
  1156. // the reference operator to avoid copying. But we want a copy here.
  1157. $env = $_ENV;
  1158. // PHP can sort an array by key, so you don't need to get keys,
  1159. // and then sort.
  1160. ksort($env);
  1161. foreach ($env as $key => $value) {
  1162. echo "{$key}={$value}\n";
  1163. }
  1164. // Literal translation of Perl example would be:
  1165. $keys = array_keys($_ENV);
  1166. sort($keys);
  1167. foreach ($keys as $key) {
  1168. echo "{$key}={$_ENV[$key]}\n";
  1169. }
  1170. // This assumes that MAX_QUOTA is a named constant.
  1171. foreach ($all_users as $user) {
  1172. $disk_space = get_usage($user);
  1173. if ($disk_space > MAX_QUOTA) {
  1174. complain($user);
  1175. }
  1176. }
  1177. // You can't modify array's elements in-place.
  1178. $array = array(1, 2, 3);
  1179. $newarray = array();
  1180. foreach ($array as $item) {
  1181. $newarray[] = $item - 1;
  1182. }
  1183. print_r($newarray);
  1184. // Before PHP 5, that is. You can precede the reference operator
  1185. // before $item to get reference instead of copy.
  1186. $array = array(1, 2, 3);
  1187. foreach ($array as &$item) {
  1188. $item--;
  1189. }
  1190. print_r($array);
  1191. // TODO: explain the old each() and list() iteration construct.
  1192. // foreach is new in PHP 4, and there are subtle differences.
  1193. // @@PLEAC@@_4.5
  1194. // Conventional 'read-only' access
  1195. foreach($array as $item)
  1196. {
  1197. ; // Can access, but not update, array element referred to by '$item'
  1198. }
  1199. // ----
  1200. // '&' makes '$item' a reference
  1201. foreach($array as &$item)
  1202. {
  1203. ; // Update array element referred to by '$item'
  1204. }
  1205. // ------------
  1206. $arraylen = count($array);
  1207. for($i = 0; $i < $arraylen; $i++)
  1208. {
  1209. ; // '$array' is updateable via subscript notation
  1210. }
  1211. // ----------------------------
  1212. $fruits = array('Apple', 'Raspberry');
  1213. foreach($fruits as &$fruit)
  1214. {
  1215. echo "{$fruit} tastes good in a pie.\n";
  1216. }
  1217. $fruitlen = count($fruits);
  1218. for($i = 0; $i < $fruitlen; $i++)
  1219. {
  1220. echo "{$fruits[$i]} tastes good in a pie.\n";
  1221. }
  1222. // ----------------------------
  1223. $rogue_cats = array('Blackie', 'Goldie', 'Silkie');
  1224. // Take care to assign reference to '$rogue_cats' array via '=&'
  1225. $namelist['felines'] =& $rogue_cats;
  1226. // Take care to make '$cat' a reference via '&$' to allow updating
  1227. foreach($namelist['felines'] as &$cat)
  1228. {
  1229. $cat .= ' [meow]';
  1230. }
  1231. // Via array reference
  1232. foreach($namelist['felines'] as $cat)
  1233. {
  1234. echo "{$cat} purrs hypnotically.\n";
  1235. }
  1236. echo "---\n";
  1237. // Original array
  1238. foreach($rogue_cats as $cat)
  1239. {
  1240. echo "{$cat} purrs hypnotically.\n";
  1241. }
  1242. // @@PLEAC@@_4.6
  1243. // PHP offers the 'array_unique' function to perform this task. It works with both keyed,
  1244. // and numerically-indexed arrays; keys / indexes are preserved; use of 'array_values'
  1245. // is recommended to reindex numerically-indexed arrays since there will likely be missing
  1246. // indexes
  1247. // Remove duplicate values
  1248. $unique = array_unique($array);
  1249. // Remove duplicates, and reindex [for numerically-indexed arrays only]
  1250. $unique = array_values(array_unique($array));
  1251. // or use:
  1252. $unique = array_keys(array_flip($array));
  1253. // ----------------------------
  1254. // Selected Perl 'seen' examples
  1255. foreach($list as $item)
  1256. {
  1257. if (!isset($seen[$item]))
  1258. {
  1259. $seen[$item] = TRUE;
  1260. $unique[] = $item;
  1261. }
  1262. }
  1263. // ------------
  1264. foreach($list as $item)
  1265. {
  1266. $seen[$item] || (++$seen[$item] && ($unique[] = $item));
  1267. }
  1268. // ------------
  1269. function some_func($item)
  1270. {
  1271. ; // Do something with '$item'
  1272. }
  1273. foreach($list as $item)
  1274. {
  1275. $seen[$item] || (++$seen[$item] && some_func($item));
  1276. }
  1277. // ----------------------------
  1278. foreach(array_slice(preg_split('/\n/', `who`), 0, -1) as $user_entry)
  1279. {
  1280. $user = preg_split('/\s/', $user_entry);
  1281. $ucnt[$user[0]]++;
  1282. }
  1283. ksort($ucnt);
  1284. echo "users logged in:\n";
  1285. foreach($ucnt as $user => $cnt)
  1286. {
  1287. echo "\t{$user} => {$cnt}\n";
  1288. }
  1289. // @@PLEAC@@_4.7
  1290. // PHP offers the 'array_diff' and 'array_diff_assoc' functions to perform this task. Same
  1291. // points as made about 'array_unique' apply here also
  1292. $a = array('c', 'a', 'b', 'd');
  1293. $b = array('c', 'a', 'b', 'e');
  1294. $diff = array_diff($a, $b); // $diff -> [3] 'd'
  1295. $diff = array_diff($b, $a); // $diff -> [3] 'e'
  1296. // Numerically-indexed array, reindexed
  1297. $diff = array_values(array_diff($a, $b)); // $diff -> [0] 'd'
  1298. $diff = array_values(array_diff($b, $a)); // $diff -> [0] 'e'
  1299. // ----------------------------
  1300. // 1st Perl 'seen' example only
  1301. $a = array('k1' => 11, 'k2' => 12, 'k4' => 14);
  1302. $b = array('k1' => 11, 'k2' => 12, 'k3' => 13);
  1303. foreach($b as $item => $value) { $seen[$item] = 1; }
  1304. // Stores key only e.g. $aonly[0] contains 'k4', same as Perl example
  1305. foreach($a as $item => $value) { if (!$seen[$item]) $aonly[] = $item; }
  1306. // Stores key and value e.g. $aonly['k4'] contains 14, same entry as in $a
  1307. foreach($a as $item => $value) { if (!$seen[$item]) $aonly[$item] = $value; }
  1308. // ----------------------------
  1309. // Conventional way: $hash = array('key1' => 1, 'key2' => 2);
  1310. $hash['key1'] = 1;
  1311. $hash['key2'] = 2;
  1312. $hash = array_combine(array('key1', 'key2'), array(1, 2));
  1313. // ------------
  1314. $seen = array_slice($b, 0);
  1315. $seen = array_combine(array_keys($b), array_fill(0, count($b), 1));
  1316. // @@PLEAC@@_4.8
  1317. // PHP offers a number of array-based 'set operation' functions:
  1318. // * union: array_unique(array_merge(...))
  1319. // * intersection: array_intersect and family
  1320. // * difference: array_diff and family
  1321. // which may be used for this type of task. Also, if returned arrays need to be
  1322. // reindexed, 'array_slice($array, 0)', or 'array_values($array)' are useful
  1323. $a = array(1, 3, 5, 6, 7, 8);
  1324. $b = array(2, 3, 5, 7, 9);
  1325. $union = array_values(array_unique(array_merge($a, $b))); // 1, 2, 3, 5…

Large files files are truncated, but you can click here to view the full file