Статьи

Субдомены в стиле Basecamp с CodeIgniter

CodeIgniter — это простая и легкая среда PHP, используемая для создания мощных веб-приложений. Сегодня мы собираемся сделать что-то изящное: мы объединим имена пользователей и субдомены, чтобы сделать их более сплоченными.

Если вы немного запутались, эта функция позволяет вашим пользователям получить доступ к своим учетным записям, введя пользовательский URL-адрес, который соответствует их имени пользователя, например, harbinger.yourapp.com .


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

Мы будем использовать вымышленный адрес nettutsapp.com и создадим пример страницы «панели инструментов»; тем не менее, вы можете относительно легко включить это в существующий проект.

Basecamp-comapre

Прежде чем начать, убедитесь, что у вас есть веб-сервер с установленным PHP. Вам также необходимо скачать CodeIgniter; в примере я использую CodeIgniter 2.0, но код должен работать на 1.7.2. Итак, начнем!


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

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

1
*.nettutsappapp.com.

Вместо этого, если вы работаете на локальном сервере, добавить субдомен подстановочного знака в файл hosts довольно сложно. Я предпочитаю добавлять отдельные записи для тестирования. Их можно удалить после того, как вы закончите. Для нашего домена нам нужно добавить четыре записи следующим образом:

  • 127.0.0.1 nettutsapp.com
  • 127.0.0.1 user1.nettutsapp.com
  • 127.0.0.1 user2.nettutsapp.com
  • 127.0.0.1 user3.nettutsapp.com

Чтобы сделать это на Mac, откройте терминал и введите sudo nano /etc/hosts . Используйте клавиши со стрелками, чтобы перейти к нижней части документа и добавить записи в нижней части файла. После этого нажмите Ctrl+X и Y чтобы подтвердить сохранение.

DNS-terminal1

Если вы используете Windows, перейдите в каталог C:\Program Files\system32\drivers\etc и откройте файл hosts в Блокноте или в предпочитаемом вами текстовом редакторе. Добавьте четыре записи, показанные выше, и сохраните файл.

Если вы внесли изменения DNS в работающий сервер, пройдет некоторое время, прежде чем вы заметите какой-либо эффект. Если вы внесли изменения в свой файл hosts, изменения будут незамедлительными.


Цель здесь состоит в том, чтобы настроить два виртуальных хоста в конфигурации Apache: один обслуживает интерфейсную страницу (домашняя страница Basecamp), а другой — страницу, видимую при доступе через поддомен (страница панели мониторинга).

Чтобы добавить новые записи, вам нужно открыть файл httpd.conf , который находится в каталоге установки Apache. Это часто находится в папке bin/apache/conf . Однако, в зависимости от конфигурации вашего сервера, расположение может отличаться.

После открытия необходимо добавить две записи, показанные ниже. Обязательно измените DocumentRoot на место по вашему выбору, которое вы создали.

Примечание. Запомните подстановочный знак и другой путь к каталогу на втором VirtualHost.

Пользователи WAMP: я рекомендую прочитать этот пост , в котором описано, как настроить VirtualHosts. Вы также можете столкнуться с проблемами разрешения; поэтому я рекомендую размещать ваши каталоги VirtualHost внутри каталога www .

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<VirtualHost *:80>
       DocumentRoot «/Users/densepixel/Sites/MAMP PRO/nettutsappfront»
       ServerName nettutsapp.com
       ServerAlias nettutsapp.com
    
       <Directory «/Users/densepixel/Sites/MAMP PRO/nettutsappfront»>
           Options -Indexes
           Options FollowSymLinks
           AllowOverride All
       </Directory>
   </VirtualHost>
    
   <VirtualHost *:80>
       DocumentRoot «/Users/densepixel/Sites/MAMP PRO/nettutsapp»
       ServerName nettutsapp.com
       ServerAlias *.nettutsapp.com
    
       <Directory «/Users/densepixel/Sites/MAMP PRO/nettutsapp»>
           Options -Indexes
           Options FollowSymLinks
           AllowOverride All
       </Directory>
   </VirtualHost>

Как только вы сохранили файл, вам нужно перезапустить Apache, чтобы изменения вступили в силу.

Убедитесь, что вы создали каталоги, которые вы указали в файле httpd.conf прежде чем запускать сервер.


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

01
02
03
04
05
06
07
08
09
10
<!DOCTYPE html>
<html lang=»»>
<head>
    <meta charset=»utf-8″>
    <title>NetTuts App Front</title>
</head>
<body>
    NetTutsApp Front
</body>
</html>

Далее откройте ваш любимый браузер и сначала проверьте адрес nettutsapp.com . Если все работает, вы должны смотреть на страницу, которую вы поместили в nettutsappfrontnettutsappfront ‘.

Затем проверьте поддомен, например. user1.nettutsapp.com ; это должно показать вам другую страницу, которую вы создали в каталоге.

конфиг-успех

Вы можете перейти к проверке других поддоменов, указанных вами в файле hosts, на которых все должны отображаться страницы, сохраненные в нашем каталоге.

В этом руководстве предполагается, что вы знаете, как установить CodeIgniter. Если нет, то вам следует взглянуть на это видеоурок Джеффри Уэя, в котором подробно объясняется этот процесс.

Поместите файлы CodeIgniter в наш каталог после удаления html страницы, которую мы создали ранее. Если вы используете CodeIgniter 1.7.2, вы можете удалить папку application из system папки.

nettutsapp-ая

Проверьте установку, user1.nettutsapp.com по URL user1.nettutsapp.com , и вы должны увидеть страницу приветствия CodeIgniter.

nettutsapp-СI-радушны

Установите CodeIgniter, как обычно, как описано в этом руководстве . Возможно, вы захотите удалить index.php из URL, автоматически загрузить некоторые библиотеки или помощники и т. Д. Для целей данного руководства нам необходимо автоматически загрузить библиотеку database и помощника по url . Откройте файл autoload.php в каталоге config и добавьте соответствующие записи.

Нам также нужно изменить контроллер по умолчанию на тот, который мы будем делать, называемый приборной панелью . Это значение можно изменить в файле /config/routes.php .

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

Самый простой способ сделать это — использовать переменную HTTP_HOST . Откройте файл config.php , найдите переменную $config['base_url'] и замените ее следующим кодом:

1
2
if(isset($_SERVER[‘HTTPS’]) && $_SERVER[‘HTTPS’] == «on»){$ssl_set = «s»;} else{$ssl_set = «»;}
$config[‘base_url’] = ‘http’.$ssl_set.’://’.$_SERVER[‘HTTP_HOST’];

Этот код разрешает HTTPS соединения, однако, если вы никогда не планируете использовать HTTPS , вы можете упростить его до base_url = $_SERVER['HTTP_HOST'] .

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

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

Таблица называется nt_subdomains в базе данных ntapp и имеет четыре поля:

  • subdomain_id (основной, авто_инкремент)
  • subdomain_name
  • user_fname
  • user_sname

Я также заполнил таблицу двумя записями, которые соответствуют поддоменам, которые мы добавили в наш файл hosts:

PHP-мой-админ

Теперь мы можем открыть конфигурацию базы данных, файл, найденный в /application/config/database.php , и отредактировать следующие значения, чтобы они соответствовали вашим личным настройкам конфигурации.

1
2
3
4
$db[‘default’][‘hostname’] = ‘localhost’;
$db[‘default’][‘username’] = ‘root’;
$db[‘default’][‘password’] = ‘root’;
$db[‘default’][‘database’] = ‘ntapp’;

И мы закончили настройку нашей установки CodeIgniter. Давайте начнем использовать поддоменов в нашем приложении.


Для этого приложения мы собираемся создать два контроллера. Первый — это контроллер error , который отображает ошибку, если поддомен не был зарегистрирован для использования в приложении. Другой контроллер — это наш основной контроллер панели мониторинга, который пользователь видит, если субдомен был добавлен в нашу базу данных.

Давайте продолжим и создадим наш контроллер ошибок. Сначала создайте новый файл в каталоге /application/controllers и назовите его error.php .
Примечание: имя файла важно

01
02
03
04
05
06
07
08
09
10
11
12
13
14
<?php
 
class Error extends Controller {
 
    function Error()
    {
        parent::Controller();
    }
 
    function index()
    {
        $this->load->view(‘error’);
    }
}

Добавьте приведенный выше код в наш новый файл error.php . Функция index загружает представление с именем error , которое мы создадим позже.

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

Создайте новый файл в каталоге controllers и назовите его dashboard.php . В этом файле нам нужно создать контроллер и загрузить представление панели мониторинга. Скопируйте код ниже и сохраните файл.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
<?php
 
class Dashboard extends Controller {
 
    function Dashboard()
    {
        parent::Controller();
    }
 
    function index()
    {
        $this->load->view(‘dashboard’);
    }
}

Страница ошибки будет отображаться, когда пользователь пытается получить доступ к поддомену, который не был зарегистрирован для использования приложением. Для целей данного учебного пособия просто создайте базовую страницу с сообщением « Субдомен не зарегистрирован» . Добавьте приведенный ниже код в новый файл с именем error.php и сохраните его в папке application / views.

01
02
03
04
05
06
07
08
09
10
11
12
<html>
<head>
    <title>Application Error : Nettuts App</title>
</head>
<body>
 
    <h1>Nettuts Application Error</h1>
 
    <p>Subdomain Not Registered</p>
 
</body>
</html>
начально-панель

В настоящее время мы будем создавать только базовую страницу панели инструментов. Вы можете использовать ту же структуру, что и при отображении ошибок, и просто изменить ее на чтение Nettuts Dashboard или что-то в этом роде. Сохраните страницу как dashboard.php в папке application/views .

Проверьте два представления, посетив URL-адреса:

  • user1.nettutsapp.com/index.php/error
  • user1.nettutsapp.com/index.php/dashboard

Работает? Давайте двигаться дальше.


Следующим шагом является извлечение имени субдомена в нашем контроллере, чтобы мы могли использовать его в запросе к базе данных.

Мы собираемся вставить наш код проверки поддоменов в функцию construct в контроллере панели мониторинга. (Под parent::Controller() ). Это означает, что поддомен будет проверен при доступе к любой функции в контроллере панели мониторинга.

Самый простой способ извлечь имя субдомена — использовать функцию explode PHP и установить разделитель на «.». Поскольку нам нужна только первая часть, мы можем разделить ее на две части, а затем назначить первую часть (имя поддомена) переменной.

Чтобы проверить это, мы можем echo переменную в самом контроллере. Смотрите код ниже:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
<?php
 
class Dashboard extends Controller {
 
    function Dashboard()
    {
        parent::Controller();
         
        $subdomain_arr = explode(‘.’, $_SERVER[‘HTTP_HOST’], 2);
        $subdomain_name = $subdomain_arr[0];
        echo $subdomain_name;
    }
 
 
}

Получите доступ к URL вашего субдомена, и вы должны увидеть правильный субдомен, отображаемый на вашей странице, как показано ниже.
Примечание. Теперь вы можете удалить оператор echo.

подобласть-parse1

Теперь, когда у нас есть доступ к имени субдомена в нашем контроллере, мы можем проверить, не было ли добавлено таблицы, которую мы создали ранее.

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

В этом уроке мы не будем использовать модели, поскольку он намного проще в обучении. CodeIgniter достаточно гибок в том, что он не заставляет вас использовать их.

Сначала нам нужно собрать запрос, как показано ниже. Этот код будет работать только в PHP5, так как он использует цепочку методов; Однако вы можете изменить его по своему вкусу.

1
2
3
// adds on from rest of construct //
$this->db->from(‘nt_subdomains’)->where(‘subdomain_name’, $subdomain_name);
$query = $this->db->get();

Мы можем использовать функцию CodeIgniter row() чтобы проверить, существует ли этот поддомен в таблице. Если это не так, то нам нужно использовать функцию перенаправления, чтобы перенаправить наших пользователей на контроллер ошибок. Следующая часть кода ниже:

1
2
3
4
5
// adds on from previous code //
if($query->num_rows() < 1)
        {
        redirect (‘error’);
        }

Давайте проверим это, user1.nettutsapp.com , который должен направить вас на страницу панели инструментов. Теперь попробуйте user3.nettutsapp.com , который должен перенаправить вас на страницу ошибки, поскольку она не была введена в таблицу.

подобласть-comapre1

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

Мы добавим функцию index в наш контроллер панели мониторинга. Сначала скопируйте код имени субдомена и запрос к базе данных, который мы использовали ранее.

1
2
3
4
5
6
7
8
9
function index()
   {
       $subdomain_arr = explode(‘.’, $_SERVER[‘HTTP_HOST’], 2);
       $subdomain_name = $subdomain_arr[0];
        
       $this->db->from(‘nt_subdomains’)->where(‘subdomain_name’, $subdomain_name);
       $query = $this->db->get();
        
   }

Мы используем функцию row() CodeIgniter для получения результата запроса. Функция row возвращает одну строку результата, что означает, что нам не нужно использовать цикл foreach ; это не нужно

1
2
// adds on from rest of index function //
$subdomain_info = $query->row();

Затем присвойте значения столбца user_fname и user_sname array $data , который затем передается в view .

1
2
3
$data[‘fname’] = $subdomain_info->user_fname;
$data[‘sname’] = $subdomain_info->user_sname;
$this->load->view(‘dashboard’, $data);

Мы можем использовать эти значения в нашем представлении, используя переменные $fname и $sname . Откройте панель инструментов и измените ее следующим образом:

1
2
3
<p>Welcome to your dashboard
   <b><?php echo $fname;
   </p>

И мы сделали! Давайте проверим это.


Попробуйте все URL-адреса, и, надеюсь, если все идет по плану, результаты должны быть следующими:

  • nettutsapp.com → Главная страница
  • user1.nettutsapp.com → Панель инструментов (Джон Доу)
  • user2.nettutsapp.com → Панель инструментов (Стив Смит)
  • user3.nettutsapp.com → Страница ошибки
конечный результат

Вот полный код, используемый для наших контроллеров и представлений:

01
02
03
04
05
06
07
08
09
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
<?php
 
class Dashboard extends Controller {
 
    function Dashboard()
    {
        parent::Controller();
         
        $subdomain_arr = explode(‘.’, $_SERVER[‘HTTP_HOST’], 2);
        $subdomain_name = $subdomain_arr[0];
         
         
        $this->db->from(‘nt_subdomains’)->where(‘subdomain_name’, $subdomain_name);
        $query = $this->db->get();
         
        if($query->num_rows() < 1)
        {
        redirect (‘error’);
        }
 
    }
 
    function index()
    {
        $subdomain_arr = explode(‘.’, $_SERVER[‘HTTP_HOST’], 2);
        $subdomain_name = $subdomain_arr[0];
         
        $this->db->from(‘nt_subdomains’)->where(‘subdomain_name’, $subdomain_name);
        $query = $this->db->get();
         
        $subdomain_info = $query->row();
        $data[‘fname’] = $subdomain_info->user_fname;
        $data[‘sname’] = $subdomain_info->user_sname;
        $this->load->view(‘dashboard’, $data);
    }
}
01
02
03
04
05
06
07
08
09
10
11
12
13
14
<?php
 
class Error extends Controller {
 
    function Error()
    {
        parent::Controller();
    }
 
    function index()
    {
        $this->load->view(‘error’);
    }
}
01
02
03
04
05
06
07
08
09
10
11
12
13
14
<html>
<head>
    <title>Dashboard : Nettuts App</title>
</head>
<body>
 
    <h1>Nettuts Dashboard</h1>
 
    <p>Welcome to your dashboard
    <b><?php echo $fname;
    </p>
     
</body>
</html>
01
02
03
04
05
06
07
08
09
10
11
12
<html>
<head>
    <title>Application Error : Nettuts App</title>
</head>
<body>
 
    <h1>Application Error</h1>
 
    <p>Subdomain Not Registered</p>
 
</body>
</html>

Конечно, этот учебник описывает только один способ получить эту изящную функциональность. Я уверен, что есть еще много; так что не стесняйтесь высказывать свои мысли и мнения в разделе комментариев ниже.