За последние 24 часа нас посетили 19309 программистов и 1605 роботов. Сейчас ищет 851 программист ...

вызов нестатических методов в статической функции

Тема в разделе "Прочие вопросы по PHP", создана пользователем Jenka156, 23 авг 2011.

  1. Jenka156

    Jenka156 Активный пользователь

    С нами с:
    23 авг 2011
    Сообщения:
    6
    Симпатии:
    0
    Здравствуйте! я программирую совсем недавно на php.
    Так вот столкнулась с такой проблемой: нужно в статической функции вызвать нестатический метод. Выглядит это примерно так:

    Код (Text):
    1.  
    2. public static function LoginUser ($log, $pass)
    3. {
    4.    $this->type("login", $log);
    5.    $this->type("pass", $pass);
    6.    $this->click($this->inLocation);
    7. }
    насколько я знаю, методы type и click прописаны как нестатические где то в исходном коде, и они наследуются моим классом, в котором создаю функцию LoginUser.
    ошибка у меня такая: Using $this when not in object context

    Скажите пожалуйста, кто знает, можно ли как нибудь вызвать нестатический метод в статической функции?
     
  2. tommyangelo

    tommyangelo Старожил

    С нами с:
    6 дек 2009
    Сообщения:
    2.549
    Симпатии:
    0
    Адрес:
    Мариуполь
    self::type("login", $log)

    Но у тебя не будет никакого $this->inLocation.

    Параметр inLocation будет только у объекта.

    Короче говоря, скорее всего ошибка в архитектуре.... Т.е. если методы используются как нестатические, в наследуемом классе тоже надо использовать их как нестатические
     
  3. Jenka156

    Jenka156 Активный пользователь

    С нами с:
    23 авг 2011
    Сообщения:
    6
    Симпатии:
    0
    теперь, когда прописываешь self::type("login", $log), то ошибка: call to undefined method.
     
  4. Jenka156

    Jenka156 Активный пользователь

    С нами с:
    23 авг 2011
    Сообщения:
    6
    Симпатии:
    0
    может тогда просто есть другой выход из ситуации?

    ситуация такая:
    есть класс "PHPUnit_Extensions_SeleniumTestCase", который является n-ным наследников других классов. там очень большая иерархия исходников.

    Так вот я наследую этот класс при написании своих программ (назовем их "Тесты"), так как где то там находятся методы, которые мне нужно использовать типа type(), click() и т.д.

    Из за того, что у меня многие методы повторяются при написании своих программ (Тестов), я вынесла эти методы в отдельный класс (назовем его "Технический"), который тоже является наследником "PHPUnit_Extensions_SeleniumTestCase".

    Если я в своем Тесте создам экземпляр класса Технический и вызову нужный метод вот так:
    $my_class = new Technical();
    $my_class->LoginUser();
    то у меня появится ошибка, потому что и Тест и Технический являются наследниками класса "PHPUnit_Extensions_SeleniumTestCase", который своим конструктором автоматически создает сессию. Получается сессия внутри сессии и ошибка.

    Чтоб не вызывать конструктор я решила сделать методы внутри технического класса статическими и вызывать их вот так:
    Technical::LoginUser();

    Ну и собственно ошибка, которая получилась в результате этого, описана выше
     
  5. tommyangelo

    tommyangelo Старожил

    С нами с:
    6 дек 2009
    Сообщения:
    2.549
    Симпатии:
    0
    Адрес:
    Мариуполь
    Jenka156

    я бы сделал так - унаследовал от PHPUnit_Extensions_SeleniumTestCase технический класс, в которой бы вынес повторяющиеся действия

    Пример

    PHP:
    1. <?php
    2.  
    3. class MyTestCase extends PHPUnit_Extensions_SeleniumTestCase
    4. {
    5.     public function login()
    6.     {      
    7.         $this->assertElementPresent('name=ContactForm[name]');
    8.         $this->type('name=ContactForm[name]','tester');
    9.         $this->type('name=ContactForm[email]','tester@example.com');
    10.         $this->type('name=ContactForm[subject]','test subject');
    11.         $this->click("//input[@value='Submit']");
    12.     }
    13.  
    14.     //и т.д.
    15. }
    А остальные тесты наследовал бы от MyTestCase

    PHP:
    1. <?php
    2. class TestUserModel extends MyTestCase
    3. {
    4.     public function doSomething()
    5.     {
    6.         $this->login();
    7.         //тут наши специфические действия
    8.     }
    9.  
    10.     //и т.д.
    11. }
     
  6. Jenka156

    Jenka156 Активный пользователь

    С нами с:
    23 авг 2011
    Сообщения:
    6
    Симпатии:
    0
    у меня была такая мысль, но тут появилась заминка. Вот пример:
    есть класс теста по созданию подразделений
    и
    есть класс теста по созданию пользователей

    Без подразделений я не могу создать пользователей, а по техническому заданию у меня каждый тест должен заканчиваться удалением всех данных, которые были созданы в процессе.

    Поэтому в тесте по созданию пользователей мне нужно будет вызвать методы для создания подразделений и использовать переменные, которые хранятся только в классе по подразделениям. Оба эти класса могут наследовать класс Технический (где описаны более общие методы типа loginUser), но мне может понадобится вызов более специфических методов. А выносить это все в технический класс будет плохо, потому что получится каша
     
  7. tommyangelo

    tommyangelo Старожил

    С нами с:
    6 дек 2009
    Сообщения:
    2.549
    Симпатии:
    0
    Адрес:
    Мариуполь
    Согласен, так будет каша.

    Но тут вопрос -
    PHP:
    1. Без подразделений я не могу создать пользователей
    - а разве нельзя в методе setUp() теста пользователей внести в базу данных тестовые подразделения, а в tearDown() их очистить? Обязательно их через Selenium забивать?
     
  8. Jenka156

    Jenka156 Активный пользователь

    С нами с:
    23 авг 2011
    Сообщения:
    6
    Симпатии:
    0
    к сожалению нельзя... у меня нет доступа к базе и работать приходится только через селениум
     
  9. tommyangelo

    tommyangelo Старожил

    С нами с:
    6 дек 2009
    Сообщения:
    2.549
    Симпатии:
    0
    Адрес:
    Мариуполь
    Jenka156

    Тогда можно попробовать написать свои классы со статическими методами и передавать туда экземпляр теста.
    Пример

    PHP:
    1. <?php
    2.  
    3. class Technical
    4. {
    5.     public static function login($object)
    6.     {
    7.          $object->assertElementPresent('name=ContactForm[name]');
    8.          $object->type('name=ContactForm[name]','tester');
    9.          $object->type('name=ContactForm[email]','tester@example.com');
    10.          $object->type('name=ContactForm[subject]','test subject');
    11.          $object->click("//input[@value='Submit']");
    12.     }
    13.  
    14. }

    Тогда внутри теста будет что-то типа такого

    PHP:
    1.  
    2. <?php
    3.  
    4. class MyTestCase extends PHPUnit_Extensions_SeleniumTestCase
    5. {
    6.     public function doSomething()
    7.     {
    8.          Technical::login($this);
    9.          
    10.          //some other actions
    11.     }
    12. }
    13.  
    14.  
     
  10. Jenka156

    Jenka156 Активный пользователь

    С нами с:
    23 авг 2011
    Сообщения:
    6
    Симпатии:
    0
    ооо! спасибо за совет! до этого я как то не додумалась) сейчас попробую!