Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP] function on a non-object
Forum PHP.pl > Forum > Przedszkole
gitbejbe
Witam. Zaczynam powoli uczyć się oop i natrafiłem na problem z którym nie za bardzo wiem jak już sobie mam poradzić.

  1.  
  2. class Validation
  3. {
  4. public $data = array();
  5. public $errors = array();
  6.  
  7. public $data2;
  8. public $kaybufor;
  9.  
  10. function __construct(array $data)
  11. {
  12. $this->data = $data;
  13. }
  14.  
  15. public function addKay($key)
  16. {
  17. $this->kaybufor = $key;
  18. }
  19.  
  20. public function addRules($rules)
  21. {
  22. $this->data2 = array($kaybufor => $rules);
  23. }
  24. }
  25.  
  26. $validation = new Validation(array(
  27. "login" => "req,min-3",
  28. "email" => "tresc 2222",
  29. "pass" => "tresc 2222",
  30. "tel" => "tresc 2222",
  31. ));
  32. $validation -> addKay('klucz') -> addRules('req,min-3'); // tutaj wywala errora: "Call to a member function addRules() on a non-object in"


blad nie wyswietla sie jesli dla obiektu $validation wywołam tylko jedną funkcje - obojętnie którą. Ogolnie w tym skrypcie chce najpierw podać klucz pola walidacji w funkcji "addKay" a potem określić zakres walidacji w funkcji "addRules". Nie wiem tylko dlaczego wywala mi ten błąd ... Mógłby mi to ktoś łopatologicznie wytłumaczyć?
Wazniak96
Dzieje się tak ponieważ odwołujesz się do obiektu którego nie ma. Jeżeli odwołanie dałbyś w nowej linijce, czyli
  1. $validation -> addKay('klucz') -> addRules('req,min-3'); //Tą linijkę rozbił na dwie części
  2.  
  3. $validation -> addKay('klucz');
  4. $validation -> addRules('req,min-3'); //Tak jest okej.


Aby móc zrobić to w jednej linijce musisz zwrócić przez return obiekt. Czyli edytować metodę addKay w taki sposób:
  1. public function addKay($key)
  2. {
  3. $this->kaybufor = $key;
  4. return $this;
  5. }
SmokAnalog
Poczytaj: http://en.wikipedia.org/wiki/Method_chaining
gitbejbe
dzięki wielkie za pomoc : )

skoro już założyłem temat, to zadam jeszcze jedno nurtujące mnie pytanie. Znalazłem w sieci klase walidacji, na której trochę chcę się wzorować. Jest troche długa ale sądzę, że na tyle czytelna, ze nie powinno być problemu:

  1. class validation {
  2.  
  3. //field with text to validation
  4. private $checkString = array();
  5.  
  6. //field with bool values; true ? false
  7. private $_is_valid = array();
  8.  
  9. //return array with errors
  10. public $error = array();
  11.  
  12. //allowed method for valid
  13. private $allowedMethod = array( 'match', 'maxlenght', 'minlenght', 'required', 'maxtimechar', 'type', 'between');
  14.  
  15. /**
  16.   * fields with error texts
  17.   *
  18.   */
  19. public $error_max_lenght = 'Too long';
  20. public $error_min_lenght = 'Too short';
  21.  
  22.  
  23. public function setString( $name, $val)
  24. {
  25.  
  26. //set arraz
  27. $this -> checkString[$name] = $val;
  28.  
  29. //return obiect
  30. return $this;
  31. }
  32.  
  33. public function setValidations( $val)
  34. {
  35. //set array
  36. $this -> name = $val;
  37.  
  38. //return obiect
  39. return $this;
  40. }
  41.  
  42. /**
  43.   * obiect chech from setValidation, if method is no allowed, is skipped
  44.   *
  45.   */
  46.  
  47. public function __call( $m, $a)
  48. {
  49. //chech whether is allowed
  50. if( in_array( $m, $this -> allowedMethod)
  51. {
  52. //set
  53. $this -> obiectString[ $this -> name][$m] = $a[0];
  54. }
  55.  
  56. //return obiect
  57. return $this;
  58. }
  59.  
  60. //start validation
  61. public function start()
  62. {
  63.  
  64. //loop array, return array from inside
  65. foreach( $this -> obiectString as $arrays => $valueArrays) {
  66.  
  67. //here too must be array
  68. if( is_array( $valueArrays)) {
  69.  
  70. //in loop
  71. //data from $valueArrays(array) loop and get names of field with strings to validation
  72. foreach( $valueArrays as $valData => $value) {
  73.  
  74. //here start validate parser
  75. switch( $valData) {
  76.  
  77. /**
  78.   * case math
  79.   * here developer can use youself regex
  80.   *
  81.   */
  82. case 'match':
  83.  
  84. if( preg_match( $value, $this -> checkString[$arrays])) {
  85.  
  86. $this -> _is_valid[$arrays][$valData] = preg_match( $value, $this -> checkString[$arrays]);
  87.  
  88. } else {
  89.  
  90. $this -> _is_valid[$arrays][$valData] = false;
  91.  
  92. //set errors array
  93. $this -> error[$arrays][] = $this -> error_match;
  94. }
  95. break;
  96.  
  97. /**
  98.   * case maxlenght
  99.   * maximum lenght of string
  100.   *
  101.   */
  102. case 'maxlenght':
  103.  
  104. if( strlen( $this -> checkString[$arrays]) <= $value) {
  105.  
  106. $this -> _is_valid[$arrays][$valData] = true;
  107. } else {
  108.  
  109. $this -> _is_valid[$arrays][$valData] = false;
  110.  
  111. //set errors array
  112. $this -> error[$arrays][] = $this -> error_max_lenght;
  113. }
  114. break;
  115.  
  116. case 'minlenght':
  117.  
  118. if( strlen( $this -> checkString[$arrays]) >= $value) {
  119.  
  120. $this -> _is_valid[$arrays][$valData] = true;
  121. } else {
  122.  
  123. $this -> _is_valid[$arrays][$valData] = false;
  124.  
  125. //set errors array
  126. $this -> error[$arrays][] = $this -> error_min_lenght;
  127. }
  128. break;
  129.  
  130.  
  131. case 'type':
  132.  
  133. //next switch
  134. switch( $value) {
  135.  
  136.  
  137. case 'string':
  138.  
  139. if( is_string($this -> checkString[$arrays])) {
  140.  
  141. $this -> _is_valid[$arrays][$valData] = TRUE;
  142.  
  143. } else {
  144.  
  145. $this -> _is_valid[$arrays][$valData] = FALSE;
  146.  
  147. //set errors array
  148. $this -> error[$arrays][] = $this -> error_type_string;
  149. }
  150. break;
  151.  
  152. }
  153. }
  154. } else {
  155.  
  156. //throw exception
  157. throw new Exception( 'Input data must be in array<br />Method: setValidations; first paramert');
  158. }
  159. }
  160. }
  161.  
  162. /**
  163.   * isValid, here return true or false
  164.   *
  165.   * @access public
  166.   * @param string @val here set name of validation string
  167.   *
  168.   */
  169.  
  170. public function isValid( $val) {
  171.  
  172. //clean buffor
  173. $unset = $this -> checkString;
  174. unset( $unset);
  175.  
  176. //multiple valid
  177. if( is_array( $val)) {
  178.  
  179. foreach( $val as $item) {
  180.  
  181. $check[] = $this -> isValid( $item);
  182. }
  183.  
  184. //check whether is minimum one time false, if is return false
  185. if( in_array( false, $check)) {
  186.  
  187. return false;
  188.  
  189. //to return true, must be all times true
  190. } else {
  191.  
  192. return true;
  193. }
  194.  
  195. } else {
  196.  
  197. //check whether is minimum one time false, if is return false
  198. if( in_array( 0, $this -> _is_valid[$val])) {
  199.  
  200. return false;
  201.  
  202. //to return true, must be all times true
  203. } else {
  204.  
  205. return true;
  206. }
  207. }
  208. }
  209.  


i teraz tak, autor tej klasy przedstawia jak powinno się z niej korzystać:

  1. $validation
  2. -> setValidations( 'first_string') -> minlenght( 15) -> maxlenght( 1574)
  3. -> setValidations( 'second_string') -> required( true)
  4. -> setValidations( 'third_string') -> required( true) -> type( 'string') -> between( array( 10,1587)) -> start();


i tutaj jest moje pytanie, bo próbuje to przeanalizować już 2 dzień i nie za bardzo mi to wychodzi...
nie wiem jak to się dzieje, że odwołując się do wartości walidacji, np "axlenght( 1574)" nie jest to odwołanie się do metody "axlenght" tylko do 'case' w metodzie start(). Albo inaczej - jeśli za bardzo zagmatwałem:
Jak to sie dzieje, ze te wszystkie wartości (np: minlenght( 15) -> maxlenght( 1574)) są analizowane dopiero w metodzie start() jako 'case' ?

ps: usunąłem pare case'ów z klasy bo temat za długi, oraz medote adderror
SmokAnalog
Dzieje się tak dlatego, że ostaje użyta magiczna metoda __call. Ona zostaje automatycznie wywołana w momencie, kiedy wywołujesz metodę, która nie istnieje. Czyli na przykładzie tej klasy, ktoś wywołuje ...->maxlength(15), a metody maxlength nie ma. Wtedy do akcji wkracza __call, której zostaje na ten moment przekazana nazwa nieistniejącej metody (maxlength) oraz parametry, z którymi próbowano ją wywołać (15). A to co się będzie działo w tym __call to już wolna amerykanka smile.gif
gitbejbe
@SmokAnalog

wielkie dzieki za wyjaśnienie, tego mi było trzeba : ) temat do zamknięcia
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.