PageRenderTime 55ms CodeModel.GetById 26ms RepoModel.GetById 0ms app.codeStats 0ms

/labs/14 Modular PHP/worksheet.md

https://gitlab.com/hungnguyen96/web_course_hungnguyen
Markdown | 219 lines | 163 code | 56 blank | 0 comment | 0 complexity | 0a13b79e4a14efaf1fd2460e747436c4 MD5 | raw file
  1. # Modular PHP
  2. In this lab you will learn to use modular features of the PHP language such as functions and classes.
  3. ## Task List
  4. in this lab you will do the following tasks:
  5. - write PHP functions
  6. - use predefined functions
  7. - use object-oriented features of PHP (classes, objects, modules)
  8. - create a JSON object that can acts as a response to an API call
  9. ### 1 Functions
  10. #### 1.1 Defining a Function
  11. A function in PHP has a same meaning as in other languages: it is a group of logically connected statements which have a name and which can
  12. be called using that name. A function can have parameters which should be named but types are not declared. A function can return a value but
  13. the type of the returned value should not be written in declaration.
  14. Syntax template is the following:
  15. ```
  16. function name($parameterName, ..., $parameterName) {
  17. statements;
  18. }
  19. ````
  20. Example:
  21. ```
  22. <?php
  23. function is_odd($number) {
  24. if (($number%2)==0)
  25. return FALSE;
  26. else
  27. return TRUE;
  28. }
  29. $checked_number=rand(0, 50); # random number generator
  30. if (is_odd($checked_number)==TRUE)
  31. print "<p>Number $checked_number is odd.</p>";
  32. else
  33. print "<p>Number $checked_number is even.</p>";
  34. ?>
  35. ```
  36. The latter if-statement looks a bit redundant. How would you get rid of it?
  37. #### 1.2 Parameter Types
  38. By default parameters are passed by value in PHP, meaning that the actual parameter ($checked_number above) value is copied into a formal parameter ($number) in each function call.
  39. This means that updating parameter value inside a function block does not affect to the value of the actual parameter in calling part of a program.
  40. A parameter can also be passed by reference which means that both parameters (actual and formal) are references to the same memory address and formal parameter can be thought as being an alias to the actual parameter. In this case a developer can pass information inside a function as well outside of it with parameters.
  41. A reference parameter should have a & mark before the usual $ mark.
  42. See the example below.
  43. ```php
  44. <?php
  45. function is_odd(&$number) { # $number is now a reference parameter
  46. if (($number%2)==0) {
  47. $number++;
  48. return FALSE;
  49. }
  50. else {
  51. $number++;
  52. return TRUE;
  53. }
  54. }
  55. $checked_number=rand(0, 50);
  56. $checked_original_value = $checked_number;
  57. if (is_odd($checked_number)==TRUE)
  58. print "<p>Number $checked_original_value is odd. (incremented value $checked_number)</p>";
  59. else
  60. print "<p>Number $checked_original_value is even. (incremented value $checked_number)</p>";
  61. ?>
  62. ```
  63. #### 1.3 Scope
  64. A variable defined outside of a function have a global scope and can be seen throughout the program. A variable which is defined inside a function are local
  65. variables and have a local scope. They can be used only inside a function block they are defined.
  66. If a function wants to access to a global variable, global keyword is needed in front of the variable name. See the example below.
  67. ```php
  68. <?php
  69. function is_odd() {
  70. global $checked_number; # global variable
  71. $number=0; # local variable (just for demo purpose)
  72. if (($checked_number%2)==0) {
  73. $number++;
  74. return FALSE;
  75. }
  76. else {
  77. $number++;
  78. return TRUE;
  79. }
  80. }
  81. $checked_number=rand(0, 50);
  82. if (is_odd($checked_number)==TRUE)
  83. print "Number $checked_number is odd.";
  84. else
  85. print "Number $checked_number is even.";
  86. ?>
  87. ```
  88. ### 2 Files
  89. PHP allows access to resources on the server. One such a resource is the files on the server. PHP has powerful and fairly easy to use file related functions.
  90. Below is a table containing some useful I/O related functions.
  91. | function names | category |
  92. | ------------------------------------------------- |:--------------------------------:|
  93. | file,file_get_contents,file_put_contents | reading/writing entire files |
  94. | basename,file_exists,filesize,fileperms,filemtime | asking for information |
  95. | is_dir,is_readable,is_writable,disk_free_space | asking for information |
  96. |copy,rename,unlink,chmod,chgrp,chown,mkdir,rmdir |manipulating files and directories|
  97. |glob,scandir |reading directories |
  98. An example below reverses lines of a text file (The example is found from the book Stepp, Miller, Kirst:"Web Programming Step bt Step").
  99. ```php
  100. <?php
  101. function reverse_lines($filename) {
  102. $text = file_get_contents($filename);
  103. $lines = explode("\n", $text); # split in lines
  104. $lines = array_reverse($lines);
  105. $text = implode("\n", $lines); # connect lines to a single string
  106. file_put_contents($filename, $text);
  107. }
  108. print file_get_contents("myfile.txt");
  109. reverse_lines("myfile.txt");
  110. print file_get_contents("myfile.txt");
  111. ?>
  112. ```
  113. ### 3 Object-oriented PHP
  114. PHP can be used as an object oriented language i.e. a developer can create classes and objects and use other object-oriented features.
  115. The syntax template for PHP class is the following:
  116. ```php
  117. class name {
  118. private $name; # member attribute (class data in each object)
  119. public function __contruct(name) { # constructor
  120. statements;
  121. }
  122. public function name(parameters) { # member method
  123. statements;
  124. }
  125. }
  126. ```
  127. As an example of a PHP class, open **diceclasses.inc.php** and study its contents. The purpose of the class is to implement a dice with a variable number of faces. For example, one can create an object that is a regular 6-face dice, a 21-face RPG dice, or a simple coin that can be emulated by a 2-face die.
  128. Furthermore, each dice keeps track of how many times it has delivered each number of eyes. These numbers of occurences are called frequencies, and, by keeping track of them, each dice can tell how many times it has landed on six, for example.
  129. Pay attention to the following points in **diceclasses.inc.php**:
  130. - The class contains encapsulated instance variables, declared as **private**. The functions are public, labeled as **public**.
  131. - The constructor is declared as a function with special name **__construct()**. The constructor can be parametrized, but there can be only one constructor. This is a limitation of PHP language that can be overcome by variable-length argument lists.
  132. - When accessing class members inside class member functions an implicit reference $this should be used.
  133. Now, open **diceplay.php**. It is a class that generates a dice object (based on user input given in URI) and generates a JSON object that contains both the indivual dice cast results as well as overall frequencies for each number of eyes.
  134. In the beginning of the file, there is an include statement:
  135. ```php
  136. include("diceclasses.inc.php");
  137. ```
  138. This causes the classes in the file to be visible into the executable script. (In this case, there is just one class named **Dice**).
  139. Pay attention to the generation of the **Dice** object that is done by **new** statement:
  140. ```php
  141. $dice = new Dice($faces);
  142. ```
  143. This automatically calls the constuctor of the **Dice** class (recall that it was named **__construct**).
  144. Now, let's test the dice. First, run **diceplay.php** to start the server.
  145. When the server is started, **diceplay.php** can be called by entering the URI of the following structure:
  146. https://wete-original-vesavvo.c9users.io/labs/14%20Modular%20PHP/diceplay.php?faces=4&throws=10
  147. In the URI, replace the domain with the one that you use. The input is given be changing the values of **faces** and **throws** parameters. In the example, there is a 4-face dice that is cast 10 times.
  148. In a fully working web application, the PHP scripts are run as a consequence of AJAX XMLHttpRequests initiated by JavaScript in browser. In this lab, you can use the aforementioned URI way to provide the input for your PHP scripts.
  149. Below is a possible JSON outcome for that call:
  150. ```
  151. {"faces":"4","results":[{"id":"1","res":"2"},{"id":"2","res":"1"},{"id":"3","res":"2"},{"id":"4","res":"4"},
  152. {"id":"5","res":"2"},{"id":"6","res":"4"},{"id":"7","res":"3"},{"id":"8","res":"4"},{"id":"9","res":"4"},{"id":"10","res":"1"}],
  153. "frequencies":[{"eyes":"1","frequency":"2"},{"eyes":"2","frequency":"3"},{"eyes":"3","frequency":"1"},{"eyes":"4","frequency":"4"}]}
  154. ```
  155. Study the contents of the output and make sure that you understand the structure of the JSON object. For viewing the structure, you can use any online JSON formatter/validator such as https://jsonformatter.curiousconcept.com/.
  156. Then, examine the source code in **diceplay.php** and find out the relatively simple steps for generating a JSON object was in PHP.
  157. Further reading: [PHP documentation home page][PHP]
  158. [PHP]: http://php.net/manual/en/
  159. ### Test Your Understanding
  160. 1. Modify the **Dice** class in **diceclasses.inc.php** to contain a function that returns the average number of eyes that the dice has given so far.
  161. 2. Add the average number of eyes (after the entire seqeunce of casts) to the resulting JSON. Use the function written above in Step 1. For instance, if the cast results are 2, 2, 6, and 1, the reported average should be 2.75.
  162. 3. Modify the **Dice** class to implement a biased dice. The bias of the dice is given as parameter *p*. For an *n*-faceted dice with bias *p*, the maximum result (*n*) is returned with probability *p*, and each of the other results is returned with probability (1-*p*)/(*n*-1). Example: Consider a six-faceted dice with a bias of 0.4. The dice returns a six with probability of 0.4, and each of the lower numbers (1 to 5) with probability 0.12. Modify the parsing of the URI in such a way that the bias can be included in the input. If the bias is not provided, the dice should be treated as unbiased.
  163. 4. In PHP, the inheritance is implemented using **extends** keyword in a fairly Java-like fashion (one of the key differences being that superclass constructors are not automatically called). In **diceclasses.inc.php**, write a new **PhysicalDice** class that becomes a subclass of **Dice**. In the subclass, add a new instance variable that is a string containing the material of the dice (e.g. wood or stone). Modify **diceplay.php** in such a way that the user can give the material of the dice as a parameter. If the material is given, a **PhysicalDice** is created. Otherwise, a regular **Dice** object is generated. For information on inheritance in PHP, see, e.g. http://zetcode.com/lang/php/oopi/ and scroll down to "Inheritance".