Debian, Dojo, Django, Python

Делюсь опытом в описанных технологиях. Блог в первую очередь выполняет роль памяток для меня самого.

Показаны сообщения с ярлыком Controller. Показать все сообщения
Показаны сообщения с ярлыком Controller. Показать все сообщения

Расширение контроллеров в Angular

Краткое содержание

В статье рассказывается о том, как в Angular можно реализовать наследование контроллеров.

Суть проблемы

Мне приходится писать довольно много кода на Angular, при этом заметил, что от контроллера к контроллеру меняются, порой, лишь незначительные части. Например, везде, где я использую ngInfiniteScroll, в $scope приходится помещать переменные allLoaded и loading, а так же обработчик loadMore(), выполняющий загрузку новых элементов. По незнанаю, приходилось многократно дублировать практически одинаковый код. Однако, один из пользователей StackOverflow нашёл очень хорошее решение данной проблемы.

Решение

Решение оказалось на удивление простым и заключается в использовании сервиса $controller.

BaseClass.js
(function (A){
    "use strict";
    // Базовый контроллер, который содержит код, общий для всех других контроллеров,
    // которые будут наследоваться от него
    A.module('App').controller('ListController', ['$scope', function($scope){
        $scope.allLoaded = false;
        $scope.items = [];
        $scope.loading = false;

        $scope.loadMore = function(){
            if ($scope.loading){
                return;
            } 
            // Тут какая-то работа по загрузке данных
        };

        $scope.refresh = function(noPlease){
            if (noPlease){
                return;
            }
            $scope.items.length = 0; // Более правильное решение, нежели $scope.items = [];
                                     // т.к. в этом случае сохраняется ссылка на оригинальный
                                     // объект
        };    
    }]);
}(this.angular));
ChildClass.js
(function(A){
    "use strict";
    A.module('App').controller('UserListController', [ '$controller', '$scope', function($controller, $scope){

            // Расширяем контроллер
            $controller('ListController', {
                $scope: $scope
            });

            // Теперь можно собственные свойства описывать
        }]);
}(this.angular));

Nginx + PHP-FPM в Debian 7

Введение

В статье рассматривается настройка сервера Debian 7 для размещения проектов PHP в связке с Nginx и PHP-FPM.

Долгое время мне вполне хватало возможностей Apache для разработки моих проектов на PHP. Были некоторые трудности с .htaccess и перенаправлением всех запросов на Front Controller, однако, чуть позже я понял, что Apache уже не может полностью удовлетворить моей тяги к максимальной производительности и начал искать другие пути. Почитав, я выяснил, что доля интернет-серверов под управлением Apache неуклонно снижается на протяжении уже нескольких лет, на замену ему приходят другие, которые дают бОльшую произодительность с меньшей затратой машинных ресурсов. Среди множества решений я выбрал PHP-FPM. Судя по тестам производительности, произведённым многими энтузиастами, именно он в связке с Nginx является наиболее перспективным способом размещения сайтов на PHP.

Цели

  • Увязка PHP-FPM с nginx
  • Конфигурирование параметров сайта для его корректной работы через Front Controller

Установка необходимого ПО

Добавим в список репозитории nginx, предварительно создав файл nginx.list в каталоге /etc/apt/sources.list.d/:

cd /etc/apt/sources.list.d/
touch nginx.list
/etc/apt/sources.list.d/nginx.list
deb http://nginx.org/packages/debian/ wheezy nginx
deb-src http://nginx.org/packages/debian/ wheezy nginx

Скачиваем ключ репозитория:

wget http://nginx.org/keys/nginx_signing.key

Установка ключей в deb-системах делается так:

apt-key add nginx_signing.key

Теперь можно выполнить установку всех необходимых программ:

apt-get update && apt-get install php5 php5-fpm nginx -y
Кратко по списку:
  • php5 и php5-fpm - интерпретатор и FastCGI-сервер для него
  • nginx - проксирующий сервер, будет нашим Front-End, т.е. сервером, принимающим запросы пользователя. Не путать с Front Controller, это совершенно разные вещи!

Настройка PHP и PHP-FPM

При установке PHP-FPM создаёт внутри каталога /etc/php5 подкаталог fpm. Внутри этого каталога находится несколько нужных нам файлов и подкаталогов. Первым делом вносим изменения в файл /etc/php5/fpm/php.ini

cd /etc/php5/fpm
nano php.ini

Здесь множество настроек, которые влияют на поведение PHP. В качестве символа комментария следует использовать точку с запятой. Самыми полезными я считаю следующие настройки:

  • short_open_tag = Off - использование коротких тегов считать ошибкой. Официальная документация по PHP рекомендует не использовать короткие теги.
  • asp_tags = Off - мы тут всё-таки на PHP пишем, а не на ASP.NET
  • max_execution_time = 60 - для некоторых CMS, например, Drupal, стандартных 30 секунд часто не хватает для выполнения некоторых скриптов, например, обновления
  • error_reporting = E_ALL - разработчику нужно видеть все ошибки. Если сервер боевой, нужно выставить в значение E_ALL & ~E_DEPRECATED & ~E_STRICT
  • display_errors = On - для разработки, для боевых условий - Off
  • display_startup_errors = On - аналогично
  • post_max_size = 16M - можно и больше, если через POST будут передаваться достаточно большие объёмы данных
  • default_charset = "UTF-8" - обязательно, если хочется избавиться от большинства проблем с кодировкой. Осторожно! Настройка влияет на весь сервер. Также кодировку можно задать в самом скрипте!
  • cgi.fix_pathinfo=1 - пригодится, если приложение работает через Front Controller
  • upload_max_filesize = 32M - можно и больше, если на сервер будут загружаться большие файлы
  • default_socket_timeout = 60 - в нашем случае связь с Nginx будет именно через сокет. Не стоит выставлять слишком большие значения, это приведёт к падению производительности.

Остальные настройки в этом файле можете делать по своему усмотрению.

Теперь нужно подредактировать файл www.conf в каталоге pool.d/www.conf

nano pool.d/www.conf

Следует изменить user и group на те, от имени которых будут выполняться скрипты. Не следует выполнять их от имени root, это дыра в безопасности. Я рекомендую указывать здесь владельца каталога /var/www

user = www-data
group = www-data

Не менее важная настройка:

listen = /var/run/php5-fpm.sock

Именно через этот сокет будет производиться обмен данными с Nginx. Остальные настройки я рекомендую оставить по умолчанию. Их тонкая настройка заслуживает отдельной подробной статьи.

После сохранения изменений следует перезапустить php-fpm:

service php5-fpm restart

Настройка Nginx

Перейдём в каталог настроек nginx:

cd /etc/nginx/

Здесь нам нужны 2 файла:

  • nginx.conf - основной файл конфигурации сервера
  • fastcgi_params - настройки Nginx для работы с FastCGI-серверами, например, PHP-FPM

Я привёл содержимое этих файлов к следующему виду:

nginx.conf
user nginx;
worker_processes 2;         # По числу ядер/процессоров, либо эмпирическим путём
worker_priority  -5;        # Отрицательные числа задают более высокий приоритет
worker_rlimit_nofile 2048;  # Можно открыть сразу 2048 подключений без изменения параметров ядра

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;

events {
    worker_connections  1024;
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    tcp_nopush      on;
    tcp_nodelay     on;

    keepalive_timeout  60; #Поддерживать подключение 1 минуту

    client_max_body_size 20m; #Разрешить загрузку файлов до 20 МБ
    server_tokens off;

    #Сжатие передаваемых данных
    gzip  on;
    gzip_disable "msie6";
    gzip_comp_level 2;
    gzip_proxied any;
    gzip_types text/plain text/css application/x-javascript text/xml application/xml+rss text/javascript;

    include /etc/nginx/conf.d/*.conf;
}
В конец файла fastcgi_params нужно добавить всего одну строчку, вот эту:
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

Теперь в каталоге /etc/nginx/conf.d/ создадим файл site.conf

nano /etc/nginx/conf.d/site.conf
index index.php;
server {
    server_name www.site.ru;
    rewrite ^ $scheme://site.ru$request_uri? permanent;
}
server {
    server_name site.ru;
    access_log /var/www/site.ru/log/access.log;
    error_log /var/www/site.ru/log/error.log;
    root /var/www/site.ru;

    location / {
        try_files $uri $uri/ /index.php?$request_uri;
        index index.php;
    }

    location ^~ /protected/ {
        deny all;
    }

    location ~ \.php$ {
        try_files $uri = 404;
        include fastcgi_params;
        fastcgi_pass unix:/var/run/php5-fpm.sock;
    }
}

Разберём по частям этот файл:

index index.php;

Считать страницей по-умолчанию index.php

server {
    server_name www.site.ru;
    rewrite ^ $scheme://site.ru$request_uri? permanent;
}

Все запросы на http://www.site.ru автоматически переадресовывать к http://site.ru/

server_name site.ru;
access_log /var/www/site.ru/log/access.log;
error_log /var/www/site.ru/log/error.log;
root /var/www/site.ru;

Собственно наш сервер, с указанием его имени, логов и указанием корневого каталога

location / {
    try_files $uri $uri/ /index.php?$request_uri;
    index index.php;
}

Тут указано, что все запросы вида http://site.ru/login/auth следует переадресовывать к http://site.ru/index.php - как раз то, что нужно для Front Controller'а

location ^~ /protected/ {
    deny all;
}

Запрещаем любые обращения к папке protected нашего сайта. Там лежат исходные коды, к которым будет обращаться только index.php, веб-сервер их отдавать не должен.

location ~ \.php$ {
    try_files $uri = 404;
    include fastcgi_params;
    fastcgi_pass unix:/var/run/php5-fpm.sock;
}

Выдавать ошибку 404, если запрошенный php-файл не найден. В остальном - просто переадресовать запрос на наш PHP-FPM-сервер. Также в этих строках выполняется подключение файла настроек /etc/nginx/fastcgi_params.

После выполнения всех операций следует перезапустить сервис Nginx

service nginx restart

Если исходные файлы сайта размещены в каталоге /var/www/site.ru/, а также этот каталог содержит подкаталог log, владельцем которого является www-data, то при обращении к сайту мы увидим главную страницу.