Форум программистов, компьютерный форум, киберфорум
PHP: ООП
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.89/18: Рейтинг темы: голосов - 18, средняя оценка - 4.89
 Аватар для nepster
61 / 61 / 11
Регистрация: 19.09.2009
Сообщений: 844

Получить объект класса по имени

24.12.2012, 20:51. Показов 3757. Ответов 13
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Получается какая проблема, работаю с loader, который подключает файлы и объявляет классы.

К примеру есть файл
test.php
PHP
1
2
3
4
5
    function __construct() 
    {
        $this->load('Drivers');   
        $this->load('DateTimei');   
     }
В нем я подключаю еще 2 файла.

Рассмотрим функцию подключения:

PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
    public function load($file = false, $part = 'admin')
    {
        $this->load = false;
        
        if($part == 'admin')
        {
            $_dir = ADMIN_PATH.'/matrix';
        }
        else if($part == 'site')
        {
            $_dir = SITE_PATH;
        }
        else 
        {
            die('Неправильный параметр $part в load()!');
        }
        
        $class = ucfirst($file);
        
        // полный адрес к файлу 
        $_obj = $_dir.'/'.$file.'.'.EXT;
        
        // проверяем существование файла с классом
        if(!file_exists($_obj))
        {
            echo 'Файл '.$_obj.' не существует!';
            die();
        }
    
        // проверим есть ли такой класс 
        if(class_exists($class, false))
        {
            echo $class.'- <br/>';
            
                print_r( get_class_methods('DateTimei'));
 
        }
        else 
        {        
            // подключаем файл с указанным классом 
            include_once($_obj);
            
            echo $class.'+ <br/>';
            
            $newclass = new $class;
            $this->$class = $newclass;  
        }
        
    }

Все работает отлично, только вот этот момент, если такой класс уже где то определен:
Как по названию класса можно получить его объект?

PHP
1
2
3
4
5
6
7
8
9
        
      // проверим есть ли такой класс 
        if(class_exists($class, false))
        {
            echo $class.'- <br/>';
            
                print_r( get_class_methods('DateTimei'));
 
        }
Я получил его свойства print_r( get_class_methods('DateTimei'));
но как получить именно объект или хотя бы как обратиться к его свойствам ?

За ранее спасибо.
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
24.12.2012, 20:51
Ответы с готовыми решениями:

Как из одного объекта получить объект другого класса?
Форумчане, подскажите. У меня есть два класса: class Category{ private $id = ''; private $parentId = ''; private...

Чем отличается объект класса от экземпляра класса
Читаю книгу &quot;PHP Объекты, шаблоны и методики программирования&quot; автор Мэт Зандстра. Перевод на русском. Там есть абзац про статические...

Свойству класса присвоить объект другого класса
Добрый день форумчане. Подскажите, пожалуйста. Свойствам класса можно при описании присваивать скалярные значения или массив. А как можно...

13
 Аватар для alpex
603 / 578 / 103
Регистрация: 16.07.2012
Сообщений: 1,762
24.12.2012, 21:08
используйте reflection
PHP
1
2
$rc = new ReflectionClass($class);
$object = $rc->newInstance();
1
 Аватар для nepster
61 / 61 / 11
Регистрация: 19.09.2009
Сообщений: 844
24.12.2012, 23:54  [ТС]
вы не много не поняли.

Вот допустим есть класс Test, мы его подключили.
Потом кто то еще раз по ошибке его подключает. И например вышло так, что
файл тест подключает тест 1, а тест 1 подключает снова тест. (вот какой-то уникум так сделает) и будет рекурсия.


Нужно, что бы:
PHP
1
2
3
4
5
6
7
8
9
10
// проверим есть ли такой класс 
        if(class_exists($class, false))
        {
            echo $class.'- <br/>';
            
            // мы попадаем сюда, если класс уже где-то объявлен 
            // и тут нам не нужно подключать еще 1 файл, а просто поменять область видимости 
            // для этого класса, но кроме как названия класса, тут ничего нет. 
 
        }
0
 Аватар для alpex
603 / 578 / 103
Регистрация: 16.07.2012
Сообщений: 1,762
25.12.2012, 00:12
если вы используете include_once или require_once, то файл не подключится второй раз
а для того что бы проверить какие классы уже инициализированы можно использовать функцию get_declared_classes() которая вернет массив всех задекларированных классов
1
 Аватар для nepster
61 / 61 / 11
Регистрация: 19.09.2009
Сообщений: 844
25.12.2012, 00:34  [ТС]
да все верно, но вот еще ошибка возникает в момент, когда мы хотим определить уже существующий класс.

Вот например:

класс 1
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class USERS_GROUPS extends SpaceView
{
    
    function __construct()
    {
        $this->load('sql_query');
        $this->load('matrix');
        $this->load('test');
    
    }
    
    
    function assign_group()
    {
       $this->Test->hello();
    } 
}
окей, все работает

теперь берем класс тест и вызываем еще раз класс матриц к примеру
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Test extends SpaceView
{
    function __construct()
    {
        $this->load('matrix');
        
    }
    
    
    function hello()
    {
        echo 'Hello World';    
          
    }
    
}


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

Что я предлагаю, я в лоадере проверяю, если класс есть, то мы его переопределим просто. Вот на этом моменте и завис.

И я не знаю к сожалению как в классе тест вызвать класс матриц.


Сам лоад, который я копаю:

PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
class SpaceView
{
    
    public function load($file = false, $part = 'admin')
    {
        $this->load = false;
        
        if($part == 'admin')
        {
            $_dir = ADMIN_PATH.'/matrix';
        }
        else if($part == 'site')
        {
            $_dir = SITE_PATH;
        }
        else 
        {
            die('Неправильный параметр $part в load()!');
        }
        
        $class = ucfirst($file);
        
        // полный адрес к файлу 
        $_obj = $_dir.'/'.$file.'.'.EXT;
        
        // проверяем существование файла с классом
        if(!file_exists($_obj))
        {
            echo 'Файл '.$_obj.' не существует!';
            die();
        }
    
        // проверим есть ли такой класс 
        if(class_exists($class, false))
        {
            echo $class.'- <br/>';
            
       
            $this->$class = $class;  
            
            
            /*
            if($class == 'DateTimei')
            {
                
                echo '<pre>';
                print_r( get_class_methods('DateTimei'));
                echo '</pre>';
            }*/
            
 
            
            //$this->$class = $class;
        }
        else 
        {        
            // подключаем файл с указанным классом 
            include_once($_obj);
            
            echo $class.'+ <br/>';
            
            $newclass = new $class;
            
            $this->$class = $newclass;  
        }
        
    }
    
 
    
}
0
 Аватар для alpex
603 / 578 / 103
Регистрация: 16.07.2012
Сообщений: 1,762
25.12.2012, 00:47
не понимаю откуда может взяться ошибка о повторном декларировании класса если вы подключаете его при помощи include_once? эта функция не подключает файл если он уже был подключен
1
 Аватар для nepster
61 / 61 / 11
Регистрация: 19.09.2009
Сообщений: 844
25.12.2012, 00:49  [ТС]
PHP
1
2
3
4
5
6
7
 // проверим есть ли такой класс 
        if(class_exists($class, false))
        {
            echo $class.'- <br/>';
            
       
            $this->$class = $class;
PHP
1
  $this->$class = $class;
дело в том, что тут $class, просто строка. И черть его знает как по имени класса получить объект
0
 Аватар для alpex
603 / 578 / 103
Регистрация: 16.07.2012
Сообщений: 1,762
25.12.2012, 00:54
файл a.php
PHP
1
2
<?php
class A{}
файл test.php
PHP
1
2
3
4
5
<?php
error_reporting(-1);
include_once('a.php');
include_once('a.php');
include_once('a.php');
нет никаких ошибок

Добавлено через 1 минуту
там вам что нужно что бы файл с классом не подключался второй раз или что бы создавался только один обьект класса, и если обьект существует то второй не создавался

Добавлено через 2 минуты
Цитата Сообщение от nepster Посмотреть сообщение
дело в том, что тут $class, просто строка. И черть его знает как по имени класса получить объект
я вам написал как создать обьектво втором сообщении, создаете отражение класса
PHP
1
$rc = new ReflectionClass($class);
и при помощи метода newInstance() класса ReflectionClass создаете обьект
PHP
1
$object = $rc->newInstance();
или можно просто создать обьект
PHP
1
$object = new $class();
1
 Аватар для nepster
61 / 61 / 11
Регистрация: 19.09.2009
Сообщений: 844
25.12.2012, 00:59  [ТС]
получается сотрите

PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class USERS_GROUPS extends SpaceView
{
    
    function __construct()
    {
        $this->load('sql_query');
        $this->load('matrix');
        $this->load('test');
    
    }
    
    
    function assign_group()
    {
       $this->Test->hello(); // я должен видеть все функции класса через $this->имя класса->функция
    } 
}



а тут момент, уже файл матриц подключен и я не могу его получить через $this->имя класса

PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Test extends SpaceView
{
    function __construct()
    {
        $this->load('matrix');
        
    }
    
    
    function hello()
    {
        echo 'Hello World';    
        $this->matrix->test(); // тоесть эта строка уже даст ошибку, так как мы не определили 
       // $this->matrix как объект класса matrix
    }
    
}




должны мы переопределить класс, что бы его было видно в дочернем классе через $this->имя класса,
но не можем, так как

PHP
1
2
3
4
5
6
if(class_exists($class, false))
        {
            echo $class.'- <br/>';
            
       
            $this->$class = $class;
не срабатывает строка $this->$class = $class;, потому, что class - просто строка с название класса.

Вот такую проблему нашел на свою голову =)
0
 Аватар для alpex
603 / 578 / 103
Регистрация: 16.07.2012
Сообщений: 1,762
25.12.2012, 01:00
а что бы не создавать кучу обьектов при каждом обращании, создаете свойство с массивом
PHP
1
private $objects = array();
и далее проверяете , если в массиве есть обьект то возвращаете его, если нет то создаете ложите в массив и возвращаете
PHP
1
2
3
4
5
6
7
8
if (isset($this->objects[$class])) {
    return $this->objects[$class];
} else {
    $rc = new ReflectionClass($class);
    $object = $rc->newInstance();
    $this->objects[$class] = $object;
    return $object;
}
1
 Аватар для nepster
61 / 61 / 11
Регистрация: 19.09.2009
Сообщений: 844
25.12.2012, 01:02  [ТС]
PHP
1
2
3
4
            $rc = new ReflectionClass($class);
            $object = $rc->newInstance();
            
            $this->$class = $object;
если сделать

PHP
1
print_r($object);
то он пустой класс создает
0
 Аватар для alpex
603 / 578 / 103
Регистрация: 16.07.2012
Сообщений: 1,762
25.12.2012, 01:08
прочитайте про шаблон пректирования registry

Добавлено через 2 минуты
Цитата Сообщение от nepster Посмотреть сообщение
то он пустой класс создает
у меня все работает
PHP
1
2
3
4
5
include_once('a.php');
$class = 'A';
$rc = new ReflectionClass($class);
    $object = $rc->newInstance();
print_r($object);
Добавлено через 1 минуту
Code
1
A Object ( )
0
508 / 358 / 13
Регистрация: 12.03.2012
Сообщений: 1,896
28.12.2012, 16:54
Зачем столько геморроя?
Читаем PSR-0 и не имеем мозг себе и другим.

Там все ответы даны о том, как загружать класс.
И еще: это стандарт.
Отхождения от него без причины - это говнокод. А говнокод - это плохо.
0
 Аватар для alpex
603 / 578 / 103
Регистрация: 16.07.2012
Сообщений: 1,762
29.12.2012, 01:37
причем здесь psr-0 если вопрос абсолютно в другом
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
29.12.2012, 01:37
Помогаю со студенческими работами здесь

Как создать объект по имени класса?
У меня имеется переменная в которой хранится имя класса, как мне по этой переменной создать объект этого класса? (конечно без использования...

Как получить объект из ресурсов по имени
Здравствуйте! Мне нужно из Properties.Resources достать изображения имя которых у меня записаны в массиве как это сделать в C#? ...

Получить значения проперти/метода класса по имени
Т.е. допустим есть класс: Class MyClass public test as String public Function getTest2() as String getTest2=&quot;1&quot; End...

Как получить указатель на объект класса CDocument
Как получить указатель на объект класса CDocument в любом месте программы? Например, функция ::AfxGetMainWnd()-&gt;GetMenu(); возвращает...

Как получить полный адрес по имени поля объекта класса
как получить полный адрес по имени поля объекта класса ? не пересчитывая размер расположенных до него полей от начала объекта


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
14
Ответ Создать тему
Новые блоги и статьи
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Programma_Boinc 28.12.2025
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост. Налог на собак: https:/ / **********/ gallery/ V06K53e Финансовый отчет в Excel: https:/ / **********/ gallery/ bKBkQFf Пост отсюда. . .
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Нашел на реддите интересную статью под названием Anyone know where to get a free Desktop or Laptop? Ниже её машинный перевод. После долгих разбирательств я наконец-то вернула себе. . .
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Рецензия / Мнение/ Перевод Нашел на реддите интересную статью под названием The Thinkpad X220 Tablet is the best budget school laptop period . Ниже её машинный перевод. Thinkpad X220 Tablet —. . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru