Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770
Форумы портала PHP.SU :: Версия для печати :: Эмуляция перегрузки в PHP, метод __call()
Форумы портала PHP.SU » » Объектно-ориентированное программирование » Эмуляция перегрузки в PHP, метод __call()

Страниц (1): [1]
 

1. romantik2011 - 30 Июля, 2011 - 01:13:44 - перейти к сообщению
Решил сделать симулировать перегрузку в PHP, написал вот такой код.
PHP:
скопировать код в буфер обмена
  1.  
  2. class A{
  3. function t($m){
  4. echo " ".$m;
  5. }
  6.  
  7. function __call($x1,$x2){
  8. function t($s1,$s2){
  9.                 $s1 = $x1;
  10.                 $s2 = $x2;
  11.                 echo $s1.' '.$s2;
  12.         }
  13. function t($s1,$s2,$s3){
  14.                 $s1 = $x1;
  15.                 $s2 = $x2;
  16.                 echo $s1.' '.$s2.' '.$s3;
  17.         }      
  18.        
  19. }
  20.  
  21. }
  22.  
  23. $obj = new A;
  24. $obj->t("Каприз");
  25. $obj->t(5,7);
  26. $obj->t("Вася",500,"Мачо");
  27.  
  28.  


Результат:
Цитата:

Каприз 5 Вася


Почему не выводится так?
Цитата:

Каприз
5 7
Вася 500 Мачо
2. DeertOff - 30 Июля, 2011 - 04:18:30 - перейти к сообщению
Цитата:
Вызовы методов могут быть перегружены с использованием методов __call, __get и __set. Эти методы будут срабатывать только в том случае, если объект или наследуемый объект не содержат метода, к которому осуществляется доступ.

+ нельзя переопределять функции а у вас в методе __call переопределена "t".
PHP:
скопировать код в буфер обмена
  1.  
  2. class A
  3. {
  4.     function t($m)// Вызываеться этот метод
  5.     {
  6.         echo " ".$m;
  7.     }
  8.      
  9.     function __call($x1,$x2)
  10.     {
  11.         function t($s1,$s2)
  12.         {
  13.             $s1 = $x1;
  14.             $s2 = $x2;
  15.             echo $s1.' '.$s2;
  16.         }
  17.        
  18.         function t($s1,$s2,$s3)
  19.         {
  20.             $s1 = $x1;
  21.             $s2 = $x2;
  22.             echo $s1.' '.$s2.' '.$s3;
  23.         }            
  24.     }    
  25. }
  26.      
  27. $obj = new A;
  28. $obj->t("Каприз");
  29. $obj->t(5,7);
  30. $obj->t("Вася",500,"Мачо");
  31.  


Тут почитай Радость
мало ли нужно: Хорошо
PHP:
скопировать код в буфер обмена
  1.  
  2. class A
  3. {
  4.     function __call($funcName,$varArr)
  5.     {
  6.         if($funcName == 't')// проверку можно убрать
  7.         {
  8.             foreach($varArr as $var)
  9.                 echo ' ' . $var;
  10.            
  11.             echo '<br />';
  12.         }      
  13.     }
  14. }
  15.      
  16. $obj = new A;
  17. $obj->t("Каприз");
  18. $obj->t(5,7);
  19. $obj->t("Вася",500,"Мачо");

(Добавление)
Возможно вы пытались реализовать что то подобное:
PHP:
скопировать код в буфер обмена
  1.  
  2. class A
  3. {
  4.     function __call($funcName,$varArr)
  5.     {
  6.         if($funcName == 't')// проверку можно убрать
  7.             $this->protoFuncT($varArr);
  8.     }
  9.    
  10.     private function protoFuncT($varArr)
  11.     {
  12.         $numVar = count($varArr);
  13.        
  14.         if($numVar == 1) //можно свичём но для наглядности
  15.         {
  16.             // тут ваш 1 метод
  17.         }
  18.         if($numVar == 2)
  19.         {
  20.             // тут ваш 2 метод
  21.         }
  22.         if($numVar == 3)
  23.         {
  24.             // тут ваш 3 метод
  25.         }
  26.         // и так далее по количеству аргументов в методе
  27.     }
  28. }
  29.  
3. romantik2011 - 03 Августа, 2011 - 19:22:01 - перейти к сообщению
Попробовал написать такой код, не выводит все три параметра почему-то. Я имею ввиду, второго перегруженного метода с именем m().
PHP:
скопировать код в буфер обмена
  1.  
  2. <?PHP
  3. class D{
  4. function m($p1,$p2){
  5.             for($i=0; $i<count($p1); $i++)
  6.                 echo $p1[$i].' ';
  7.                 echo ' '.$p2;
  8.         }
  9. function __call($n,$v)  {
  10.                 foreach($v as $z=>$f){
  11.                         echo $v. ' '.$f;
  12.                 }
  13.         }
  14.  
  15.        
  16. }
  17. $x = new D;
  18. $p = array("Динозавр","Аладин",954);
  19. $g = array("Ура!");
  20.  
  21. $x->m($p,"2-ой параметр<br />");
  22. $x->m($g,"Санчо","3-ий параметр<br />");
  23.  
  24. ?>
  25.  
  26.  
4. Мелкий - 03 Августа, 2011 - 19:36:43 - перейти к сообщению
romantik2011, в PHP нет перегрузки методов и функций. А __call вызывается только тогда, если не определён запрашиваемый метод.
5. romantik2011 - 03 Августа, 2011 - 19:41:39 - перейти к сообщению
Ясно, но почему-то цикл фор-ич не подставил значения.
Я изменил вот эту строку:
PHP:
скопировать код в буфер обмена
  1. $x->m($g,"Санчо","3-ий параметр");

на эту
PHP:
скопировать код в буфер обмена
  1. $x->s($g,"Санчо","3-ий параметр");


Получил такой результат:
Цитата:
Динозавр Аладин 954 2-ой параметр
Array ArrayArray СанчоArray 3-ий параметр

Почему форич значения не подстаивл, а вывалил всё Array вместо значений?
6. LIME - 03 Августа, 2011 - 20:37:16 - перейти к сообщению
romantik2011 пишет:
foreach($v as $z=>$f){
                        echo $v. ' '.$f;
                }
 

надо echo $z. ' '.$f;
при выводе массива целиком выводится слово array
7. Мелкий - 03 Августа, 2011 - 20:58:30 - перейти к сообщению
Сэмулировать перегрузку можно, например, так:
PHP:
скопировать код в буфер обмена
  1. class foo {
  2. public function bar() {
  3. switch (func_num_args()) {
  4. case 1:
  5. $this->bar1(func_get_arg(0)); //запустим с одним входящим аргументом
  6. break;
  7. case 2:
  8. $this->bar2(func_get_arg(0),func_get_arg(1)); //с двумя
  9. break;
  10. }
  11. }
  12. private function bar1( $arg1) {
  13. }
  14.  
  15. private function bar2( $arg1, $arg2) {
  16. }
  17. }
8. romantik2011 - 03 Августа, 2011 - 20:58:45 - перейти к сообщению
Проблема в том что массив не извлекается, вместо него слово Array при выводе.
Значение массива не выводит, выводит вместо значения просто слово Array
9. LIME - 03 Августа, 2011 - 21:10:28 - перейти к сообщению
LIME пишет:
при выводе массива целиком выводится слово array

romantik2011 пишет:
Значение массива не выводит, выводит вместо значения просто слово Array
это нормальное поведение
чтобы вывести массив надо выводить поэлементно
(Добавление)
или var_dump print_r
10. romantik2011 - 03 Августа, 2011 - 21:18:41 - перейти к сообщению
А почему только вот так сработало? Почему без внутреннего цикла не запахало и без всяких проверок и приведений типов?
Кто-нибудь подскажет как реализовать не так громоздко цикл форич?
PHP:
скопировать код в буфер обмена
  1.  
  2. <?PHP
  3. class D{
  4. function m($p1,$p2){
  5.         for($i=0; $i<count($p1); $i++)
  6.         echo $p1[$i].' ';
  7.         echo ' '.$p2;
  8.     }
  9.        
  10. function __call($n,$v)  {
  11.         foreach($v as $f){
  12.              if ((string)$f == "Array")
  13.                          foreach($f as $v)
  14.                          {
  15.                             echo $v;
  16.                          }
  17.           else echo $f.' ';
  18.         }
  19.     }
  20.      
  21. }
  22. $x = new D;
  23. $p = array("Динозавр","Аладин",954);
  24. $g = array("Ура!");
  25.  
  26. $x->m($p,"2-ой параметр<br />");
  27. $x->s($g,"Санчо","3-ий параметр");
  28.  
  29. ?>
  30.  
11. Opo6ac - 17 Августа, 2011 - 11:32:00 - перейти к сообщению
Мелкий пишет:
romantik2011, в PHP нет перегрузки методов и функций. А __call вызывается только тогда, если не определён запрашиваемый метод.

Минуточку, а что такое тогда интерфейсы? - ведь при последующей реализации они как раз перегружаются.
12. Мелкий - 17 Августа, 2011 - 12:15:38 - перейти к сообщению
Opo6ac пишет:
Минуточку, а что такое тогда интерфейсы?

Абстрактный класс.
Но в отличии от сущности, объявленной абстрактным классом, интерфейсов у класса может быть несколько, но только если их методы не перекрываются между собой! http://habrahabr[dot]ru/blogs/php/116916/

И в этом случае не перегрузка, а реализация метода. Т.к. у интерфейса есть только определение. Почитайте про перегрузку методов и функций в C++, поймёте, о чём речь.
13. Opo6ac - 17 Августа, 2011 - 13:07:57 - перейти к сообщению
Мелкий, ага, я уже проникся проблемой. Оказывается, оно даже в 6й версии не планируется.
Будьте так любезны, посмотрите соседнюю тему - я там пытаюсь как раз.. вот теперь даже не знаю, как называется то, что я пытаюсь делать. Наверное, переопределить метод с сохранением прежнего функционала.

 

Powered by ExBB FM 1.0 RC1