Статьи

Создайте свое приложение в облаке с помощью Heroku и Facebook SDK

Когда я впервые столкнулся с Heroku, это был облачный сервис только для Ruby. Я не был разработчиком Ruby, поэтому быстро забыл об этом. Но затем они установили партнерские отношения с Facebook, и вы могли создать приложение Facebook, размещенное на Heroku, с помощью PHP-SDK Facebook всего за пару кликов.

Теперь вопрос: возможно ли создать приложение PHP с Heroku, которое работает как снаружи, так и внутри Facebook? Ответ — да, и я покажу вам, как.

В этой статье вы создадите простое приложение для обмена ссылками. Пользователь может поделиться URL-адресом с заголовком и необязательным описанием. Каждый пользователь идентифицируется по имени и адресу электронной почты (который остается приватным). Если пользователь запускает приложение в Facebook, поля имени и адреса электронной почты берутся из его профиля.

Создайте свою учетную запись Heroku

Все, что вам нужно для начала работы с Heroku, — это создать бесплатную учетную запись; это займет всего 5 минут и адрес электронной почты.

Основное использование Heroku бесплатно. Как указано в документации к платформе, «каждое создаваемое вами приложение имеет бесплатный доступ к 750 динамочам в месяц и базе данных по 5 МБ». Dyno — это отдельный веб-процесс, отвечающий на запросы HTTP и выполняющий ваш код.

Если вы хотите воспользоваться HTTPS, вам необходимо подтвердить свою учетную запись Heroku с помощью кредитной карты. Это необходимо, если вы хотите обслуживать свое приложение Facebook через HTTPS, но вам не будет выставлен счет, если вы используете базовое дополнение SSL.

Установите инструменты торговли

Процесс разработки Heroku основан на Ruby и Git — утилита командной строки heroku является драгоценным камнем Ruby, и каждый раз, когда вы нажимаете свой код с помощью Git, приложение будет обновляться в режиме реального времени. Таким образом, вам необходимо:

  1. Установите Ruby (в OSX версия 1.8.x уже установлена, что нормально).
  2. Установите Git.
  3. Установите драгоценный камень Heroku (так же просто, как драгоценный камень sudo, установите heroku).
  4. Сконфигурируйте свою среду, используя свои учетные данные Heroku и ключи SSH.

Лучший способ сделать все это — следовать руководству по началу работы с Heroku.

Также для этого проекта вы хотите установить гем Taps, чтобы помочь переносить базы данных.
[sourcecode language = ”bash”] Vitos-Laptop: ~ vito $ sudo gems установить краны [/ sourcecode]

Создайте свое приложение

Чтобы создать приложение, вы напишите свой код локально, инициализируете репозиторий Git, а затем отправите код в Heroku.

Создайте свое приложение локально

Создайте пустой каталог для своего приложения и настройте свой локальный веб-сервер.
[sourcecode language = ”bash”]
Vitos-Laptop: ~ vito $ cd / Пользователи / Общий / Веб-сервер / Сайты
Витос-ноутбук: сайты vito $ mkdir HeroLinks
[/исходный код]
Настройте свой локальный веб-сервер с новым сайтом, который указывает на этот каталог с URL-адресом, таким как http: //herolinks.local.

Init Your Git Repository

Инициализируйте свой репозиторий в каталоге приложения:
[sourcecode language = ”bash”]
Витос-ноутбук: сайты vito $ cd HeroLinks
Vitos-Laptop: HeroLinks vito $ git init
Инициализированный пустой Git-репозиторий в .git /
Витос-ноутбук: HeroLinks vito $ cat
Vitos-Laptop: HeroLinks vito $ git add.
Vitos-Laptop: HeroLinks vito $ git commit -m «Приложение HeroLinks создано».
[/исходный код]

Создать приложение на Heroku

По умолчанию Heroku использует среду Ruby для своих размещенных приложений. Чтобы создать приложение PHP, вам нужно настроить аргументы команды для использования стека с именем cedar. Команда для создания приложения выглядит следующим образом:
[sourcecode language = ”bash”] Vitos-ноутбук: HeroLinks vito $ heroku создать HeroLinks — стековый кедр
Создание herolinks… готово, стек кедровый
http://herolinks.herokuapp.com/ | [email protected]: herolinks.git
Git удаленную героку добавил
[/исходный код]

С помощью этой команды Heroku создает приложение и удаленный репозиторий, а затем возвращает URL-адрес и сведения о приложении.

Вы публикуете свою заявку со следующим:

[sourcecode language = ”bash”] Vitos-портативный компьютер: HeroLinks vito $ git push heroku master [/ sourcecode]

Вы должны создать и зафиксировать хотя бы один файл, иначе команда не будет выполнена. Я создал файл index.php с приветственным сообщением.

Вывод на push должен выглядеть примерно так:
[sourcecode language = ”bash”]
Подсчет объектов: 3, сделано.
Написание объектов: 100% (3/3), 253 байта, сделано.
Всего 3 (дельта 0), повторно 0 (дельта 0)

—–> Heroku получает толчок
—–> Обнаружено приложение PHP
—–> Комплектация Apache v2.2.19
—–> Пакетирование PHP v5.3.6
—–> Обнаружение типов процессов
Procfile объявляет типы -> (нет)
Типы по умолчанию для PHP -> веб
—–> Размер скомпилированного слага составляет 21,5 МБ
—–> Запуск… готово, v4
http://herolinks.heroku.com развернут в Heroku

Для [email protected]: herolinks.git
* [новая ветка] master -> master
[/исходный код]

Начать кодирование

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

  • Bootstrap — CSS-инструментарий от Twitter (для оформления интерфейса)
  • Slim — легкий, но мощный PHP-фреймворк (для основного контроллера)
  • пара библиотек, извлеченных из платформы CakePHP (для проверки и очистки данных)
  • простой класс базы данных обертки PDO (самодельный)

Как видно из следующей структуры каталогов, приложение очень простое.

Структура каталогов приложения Heroku

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

Каталог lib содержит библиотеки PHP, а папка с именем templates содержит файлы интерфейса. У меня есть три страницы: домашняя страница, которая отображает список всех общих ссылок (home.php), страница с формой, необходимой для отправки новой ссылки (new.php), и страница результатов поиска (search.php) ,

Доступ к базе данных

Платформа Heroku предоставляет каждому приложению Ruby общую базу данных PosgreSQL объемом 5 МБ. Для приложений PHP общая база данных не создается по умолчанию и должна быть добавлена ​​с помощью команды:
[sourcecode language = ”bash”] Vitos-Laptop: HeroLinks vito $ heroku addons: добавить базу данных общего доступа [/ sourcecode]
Каждое приложение имеет доступ к базе данных, используя специальную переменную среды DATABASE_URL, которая содержит строку подключения. Он доступен из вашего PHP-кода с помощью $ _ENV [«DATABASE_URL»].

Если вы приобрели специальную надстройку базы данных, например Heroku Postgres, вы можете использовать консольное приложение psql для управления вашей базой данных. Для общих баз данных вы должны управлять ими вручную, за исключением утилит импорта / экспорта db: push и db: pull.

У меня не установлен PosgreSQL на моем локальном компьютере, поэтому мой код использует SQLite локально, а каталог данных содержит мою базу данных. Вот как я переключаюсь между PostgreSQL и SQLite в коде:
[sourcecode language = ”php”] <? php
// если $ _ENV [«DATABASE_URL»] пусто, то приложение не работает на Heroku
if (пусто ($ _ ENV [«DATABASE_URL»])) {
$ config [«db»] [«driver»] = «sqlite»;
$ config [«db»] [«url»] = «sqlite: //». Realpath ( «данные / my.db»);
}
еще {
// переводим URL базы данных в дружественный PDO DSN
$ url = parse_url ($ _ ENV [«DATABASE_URL»]);
$ config [«db»] [«driver»] = $ url [«схема»];
$ config [«db»] [«url»] = sprintf (
«PgSQL: пользователь =% s, пароль =% s, хозяин =% s; имя_бд =% s»,
$ url [«user»], $ url [«pass»], $ url [«host»],
trim ($ url [«path»], «/»));
}[/исходный код]
Сначала я устанавливаю базу данных SQLite по умолчанию, если $ _ENV [«DATABASE_URL»] пусто, так как это означает, что приложение не работает на Heroku. Если приложение работает на Heroku, я анализирую URL базы данных и преобразую его в строку подключения, удобную для PDO. URL выглядит так:
[sourcecode language = ”php”] postgres: // имя пользователя: пароль @ хост / база данных [/ sourcecode]
и выглядит так после преобразования:
[sourcecode language = ”php”] pgsql: user = имя пользователя; пароль = пароль; host = host; dbname = database [/ sourcecode]

Главный контроллер приложений

Файл index.php является основным контроллером приложения. После настройки базы данных происходит настройка Facebook, загрузка других библиотек PHP, а затем создается новый экземпляр объекта приложения Slim.
[sourcecode language = ”php”] <? php
// Загрузить ядро ​​Slim Framework …
require_once «lib / Slim / Slim.php»;

//… добавить другие вспомогательные библиотеки
require_once «lib / db / db.class.php»;
require_once «lib / cake / sanitize.php»;
require_once «lib / cake / validation.php»;

// а затем Facebook SDK
require_once «lib / facebook / facebook.php»;

// Создание нового приложения Slim
$ app = new Slim (); [/ sourcecode]
Здесь я создаю приложение Slim, используя его настройки по умолчанию, я также мог бы передать ассоциативный массив настроек, но пока достаточно настроек по умолчанию.

Я использую Slim для сопоставления URL-адресов приложения с функциями PHP. Приложение имеет четыре URL-адреса: / (корень), / новый, / поиск и / установить.

С Slim вы можете сопоставить URL-адрес с различными функциями, которые обрабатывают различные методы HTTP, или вы можете сопоставить одну и ту же функцию с одним или несколькими методами HTTP. Я хочу, чтобы мой корневой URL-адрес был доступен с помощью методов GET и POST, потому что когда он выполняется внутри элемента iframe Facebook, он получает некоторые данные POST из среды размещения, называемой подписанным запросом. Вот как это сделать:
[sourcecode language = ”php”] <? php
$ app-> map («/», function () use ($ app, $ config) {
// сделай что-нибудь
}) -> via («GET», «POST»);
[/исходный код]

Код отображает корневой URL на анонимную функцию, разрешающую только методы GET и POST HTTP. Функция вызывается всякий раз, когда пользователь запрашивает корневой URL-адрес приложения, используя GET или POST.

Установщик приложений

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

Функция, связанная с URI / install, сначала проверяет глобальную переменную $ config, чтобы определить, в какой среде выполняется. Если вы работаете в локальной системе, то запрос на создание таблицы выполняется с использованием стандартных операторов PDO.
[sourcecode language = ”php”] <? php
$ app-> get («/ install», function () use ($ app) {
глобальный $ config;
// проверка драйвера и установка только для SQLite / local
if ($ config [«db»] [«driver»] == «sqlite») {
if ($ db = Db :: getConnection ()) {
$ query = «CREATE TABLE ЕСЛИ НЕ СУЩЕСТВУЕТ ссылки (
id INTEGER ПЕРВИЧНЫЙ КЛЮЧ,
URL VARCHAR (255),
название VARCHAR (100),
описание VARCHAR (512),
имя пользователя VARCHAR (50),
используйте remail VARCHAR (100),
создан DATE DEFAULT (datetime (‘now’, ‘localtime’))
) «;
пытаться {
$ stmt = $ db-> prepare ($ query);
$ Stmt-> Execute ();
$ app-> flash («info», «Приложение успешно установлено!»);
$ App-> редирект ( «/»);
}
catch (PDOException $ e) {
$ app-> flashNow («error», «Невозможно установить приложение:».
$ E-> GetMessage ());
}
}
еще {
$ app-> flashNow («ошибка», «Невозможно открыть БД»);
}
}
еще {
$ app-> flashNow («info», «Команда Install предназначена только для локального / SQLite, попробуйте вместо этого запустить <code> heroku db: push sqlite: //data/my.db </ code>!»);
}
$ app-> render («default.php», массив («action» => «install»));
});

[/исходный код]

Переменная $ db является объектом PDO, статический метод Db :: getConnection () заботится об управлении соединением и возвращает NULL в случае ошибки.

Метод flash () сохраняет сообщение в текущем сеансе, присваивая ему метку ключа «info». Затем сообщение доступно для следующего запроса (т. Е. На следующей странице).

У меня также есть метод flashNow (); сообщение, сохраненное с помощью этого метода, доступно в текущем запросе внутри переменной $ flash.

Используя соответствующие ключи (например, ошибка, информация, предупреждение и т. Д.), Я могу соответствующим образом стилизовать сообщение, используя предварительно созданные стили CSS Bootstrap, например:
[sourcecode language = ”php”]
<? PHP
if (! empty ($ flash [«error»])) {
?>
<div class = «error-message error»>
<? php echo $ flash [«error»]?>
</ DIV>
<? PHP
}

[/исходный код]

Метод render () принимает два параметра:

  • файл представления PHP (или HTML) для рендеринга
  • ассоциативный массив переменных, которые передаются в файл представления

В этом случае я передаю переменную с именем «action», содержащую значение «install»; файл default.php будет иметь локальную переменную $ action для использования. По умолчанию файлы представлений помещаются в каталог шаблонов, но этот путь можно настроить с помощью API конфигурации Slim (дополнительную информацию см. В руководстве Slim). Когда ваша база данных функционирует локально, вы можете использовать инструменты Heroku для импорта схемы (и данных, если они найдены) в удаленную базу данных.

[sourcecode language = ”php”] Vitos-портативный компьютер: HeroLinks vito $ heroku db: push sqlite: //data/my.db [/ sourcecode]

Вывод должен выглядеть примерно так:
[sourcecode language = ”php”] Loaded Taps v0.3.23
Предупреждение: данные в приложении «herolinks» будут перезаписаны и не подлежат восстановлению.

! ВНИМАНИЕ: потенциально разрушительные действия
! Эта команда повлияет на приложение: herolinks
! Чтобы продолжить, введите «herolinks» или повторно запустите эту команду с –confirm herolinks [/ sourcecode]

Введите имя вашего приложения, чтобы подтвердить импорт, и ваша база данных будет импортирована в Heroku.

Поток приложений

Остальная часть приложения проста и использует подход, аналогичный шаблону Model-View-Controller, за исключением того, что нет модели.

Домашняя страница выбирает последние 10 ссылок из базы данных, используя общий запрос SQL. Результаты сохраняются в массиве $ links и передаются в файл представления (home.php) методом render ().
[sourcecode language = ”php”]
<? PHP
$ app-> map («/», function () use ($ app) {
$ pageTitle = «Последние ссылки»;
$ action = «home»;
$ links = array ();
if ($ db = Db :: getConnection ()) {
$ query = «SELECT * FROM links ORDER BY созданного DESC LIMIT 10»;
пытаться {
foreach ($ db-> query ($ query) как $ link) {
$ links [] = $ link;
}
}
catch (PDOException $ e) {
$ app-> flashNow («error», $ e-> getMessage ());
}
}
еще {
$ app-> flashNow («ошибка», «Невозможно открыть БД»);
}
$ app-> render («home.php», массив (
«pageTitle» => $ pageTitle,
«действие» => $ действие,
«links» => $ links));
}) -> via («GET», «POST»);

[/исходный код]

[sourcecode language = ”php”]
<? PHP
if (! empty ($ links)) {
?>
<h2> Последние ссылки </ h2>
<table class = «linklist zebra-striped» summary = «Последние отправленные ссылки»>
<TR>
<Й> Сайт </ е>
<Й> Описание </ е>
<Й> Пользователь </ й>
<Й> Дата </ е>
</ TR>
<? PHP
foreach ($ links как $ link) {
?>
<TR>
<td> <a href=»<?php echo $link[«url»] ?> «rel =» external «> <? php echo $ link [» title «]?> </a> </ td>
<td> <? php echo $ link [«description»]?> </ td>
<td> <? php echo $ link [«username»]?> </ td>
<td> <? php echo date («d FYH: i», strtotime ($ link [«созданный»]))?> </ td>
</ TR>
<? PHP
}
?>
</ Table>
<? PHP
}
еще {
?>
<div class = «Информация о блоке сообщений о предупреждениях»>
<p> Извините, база ссылок пуста! </ p>
<div class = «alert-actions»> <a class=»btn primary» href=»/new»> Добавить ссылку </a> </ div>
</ DIV>
<? PHP
}

[/исходный код]

Страница «Добавить ссылку» извлекает данные формы, используя методы Slim () -> isPost () и request () -> post (). Данные очищаются и проверяются с помощью классов Sanitize и Validation из платформы CakePHP.
[sourcecode language = ”php”]
<? PHP
$ app-> map («/ new», function () use ($ app) {
$ pageTitle = «Добавить новую ссылку»;
$ action = «new»;
$ data = array ();
$ errors = array ();
if ($ app-> request () -> isPost ()) {
$ data = $ app-> request () -> post ();
$ data = Sanitize :: clean ($ data, array («escape» => false));

$ valid = Validation :: getInstance ();
if (! $ valid-> email ($ data [«useremail»])) {
$ errors [«useremail»] = «Неверный адрес электронной почты»;
}
if (! $ valid-> notEmpty ($ data [«username»])) {
$ errors [«username»] = «Пожалуйста, введите ваше имя»;
}
if (! $ valid-> notEmpty ($ data [«title»])) {
$ errors [«title»] = «Пожалуйста, введите заголовок»;
}
if (! $ valid-> url ($ data [«url»])) {
$ errors [«url»] = «Неверный или пустой URL»;
}

if (empty ($ errors)) {
if ($ db = Db :: getConnection ()) {
$ query = «INSERT INTO links (url, title, description, username, useremail) VALUES (: url,: title,: description,: username,: useremail)»;
пытаться {
$ stmt = $ db-> prepare ($ query);
$ stmt-> bindParam («: url», $ data [«url»]);
$ stmt-> bindParam («: title», $ data [«title»]);
$ stmt-> bindParam («: description», $ data [«description»]);
$ stmt-> bindParam («: имя пользователя», $ data [«имя пользователя»]);
$ stmt-> bindParam («: useremail», $ data [«useremail»]);
$ Stmt-> Execute ();
$ app-> flash («информация», «Ссылка успешно добавлена!»);
$ App-> редирект ( «/»);
}
catch (PDOException $ e) {
$ app-> flashNow («error», «Невозможно сохранить ваш URL:». $ e-> getMessage ());
}
}
еще {
$ app-> flashNow («ошибка», «Невозможно открыть БД»);
}
}
}

$ app-> render («new.php», массив (
«pageTitle» => $ pageTitle,
«действие» => $ действие,
«data» => $ data,
«ошибки» => $ ошибок));

}) -> via («GET», «POST»);

[/исходный код]

Ошибки хранятся в массиве $ errors, который используется и контроллером, и представлением. Контроллер проверяет наличие ошибок, чтобы определить, должны ли данные быть вставлены в базу данных, и представление для отображения сообщения об ошибке рядом с каждым полем формы.

[sourcecode language = ”php”]
<form action = «» method = «post» accept-charset = «utf-8»>
<FIELDSET>
<div class = «clearfix <? php if (! empty ($ errors [» url «])) echo» error «?>»>
<label for = «url»> URL сайта </ label>
<div class = «input»>
<input type = «text» size = «30» name = «url» id = «url» class = «xlarge» value = «<? php echo (! empty ($ data [» url «]))? $ data [«url»]: «»;?> «>
<? PHP
$ field = «url»;
if (! empty ($ errors [$ field])) {
?>
<span class = «help-inline»> <? php echo $ errors [$ field]?> </ span>
<? PHP
}
?>
</ DIV>
</ DIV>
<! — Другие поля здесь ->
</ FIELDSET>
</ Форма>

[/исходный код]

Подготовленные PDO операторы используются для вставки данных в базу данных, заключенных в блок try-catch. Метод flashNow () отображает любые сообщения об ошибках PDO (хотя, очевидно, в производственной среде этого следует избегать).

Страница поиска похожа на домашнюю страницу, но отличается от обработки условия поиска перед выполнением запроса SQL.
[sourcecode language = ”php”]
<? PHP
$ app-> get («/ search (/: key)», функция ($ key = null) use ($ app) {
$ pageTitle = «Поиск ссылок»;
$ action = «search»;
$ links = array ();
if ($ app-> request () -> isGet ()) {
if (empty ($ key)) {
$ key = $ app-> request () -> get («key»);
}
$ key = Sanitize :: clean ($ key, array («escape» => false));
}

if ($ db = Db :: getConnection ()) {
$ query = «SELECT * FROM links WHERE (название LIKE: ключ ИЛИ url LIKE: ключ) ORDER BY созданный DESC»;
пытаться {
$ stmt = $ db-> prepare ($ query);
$ needle = «%». $ ключ. «%»;
$ stmt-> bindParam («: ключ», $ needle, PDO :: PARAM_STR);
$ Stmt-> Execute ();
while ($ link = $ stmt-> fetch (PDO :: FETCH_ASSOC)) {
$ links [] = $ link;
}
}
catch (PDOException $ e) {
$ app-> flashNow («error», «Невозможно выполнить поиск:». $ e-> getMessage ());
}
}
еще {
$ app-> flashNow («ошибка», «Невозможно открыть БД»);
}

$ app-> render («search.php», массив (
«pageTitle» => $ pageTitle,
«действие» => $ действие,
«ключ» => $ ключ,
«links» => $ links));
});

[/исходный код]

Синтаксис $ app-> get («/ search (/: key)», function ($ key = null) означает, что любая строка после имени действия / search обрабатывается как поисковый термин и сохраняется внутри параметра $ key для В любом случае переменная $ key очищается перед использованием.

Добавление функциональности Facebook

Приложение хорошо работает в автономном режиме, но чтобы использовать его внутри Facebook и использовать данные пользователя, вам необходимо:

  • скачать PHP PHP SDK с GitHub
  • зарегистрируйте свое приложение в Facebook, начиная со страницы разработчика

Я скопировал каталог src SDK в каталог lib моего приложения и переименовал его в facebook.

Чтобы зарегистрировать приложение Facebook, вы должны предоставить некоторые данные, такие как URL-адрес приложения (например, http://myapp.heroku.com) и название холста (например, myapp), который является идентификатором для приложение внутри Facebook (например, https://apps.facebook.com/myapp/).

Примечание: можно пропустить URL HTTPS. При этом ваше приложение может использоваться только с отключенной опцией безопасного режима (для получения дополнительной информации проверьте настройки своей учетной записи Facebook).

После того как ваше приложение зарегистрировано в Facebook, вы можете предоставить информацию о конфигурации в контроллере index.php:
[sourcecode language = ”php”] <? php
$ config [«facebook»] [«appId»] = «YOUR_APP_ID»;
$ config [«facebook»] [«secret»] = «YOUR_APP_SECRET»;
$ config [«facebook»] [«canvas»] = «your-app-canvas»;
$ config [«facebook»] [«canvas_url»] = «https://apps.facebook.com/your-app-canvas/»;[/sourcecode]

Вам также необходимо указать другой параметр конфигурации, домашний URL, который передается в API авторизации:
[sourcecode language = ”php”] <? php
$ config [«app»] [«home»] = «https://your-app.heroku.com»; [/ sourcecode]

Интеграция с Facebook происходит в двух разделах кода. Первый создает новый объект Facebook как свойство объекта $ app. Преимущество этого подхода заключается в том, что у вас есть доступ к этому соединению везде, где у вас есть доступ к объекту приложения. Установите свойство facebookCanvas, чтобы сообщить приложению, что оно работает внутри iframe, предоставленного Facebook.
[sourcecode language = ”php”] <? php
$ app = new Slim ();
$ app-> Facebook = новый Facebook ($ config [«facebook»]);
$ app-> facebookUserProfile = null;
$ app-> facebookCanvas = isRunningInsideFacebook ();

[/исходный код]

Второй точкой интеграции является функция isRunningInsideFacebook (), которая сообщает приложению, работает ли оно в Facebook (по сути, оно проверяет переменную Sign_request, отправленную с помощью метода HTTP POST).

[sourcecode language = ”php”] <? php
функция isRunningInsideFacebook () {
return! empty ($ _ REQUEST [«signature_request»]);
}[/исходный код]

Функция facebookInit () позаботится обо всем остальном. Например, он проверяет, имеет ли он право авторизации. Подписанный запрос анализируется с помощью Facebook SDK в поисках поля user_id. Если у него нет этого поля, приложение не авторизуется пользователем и перенаправляет его на страницу авторизации.
[sourcecode language = ”php”]
<? PHP
function facebookInit () {
глобальное приложение $;
глобальный $ config;

if ($ fbData = $ app-> Facebook-> getSignedRequest ()) {
// перенаправить на авторизацию Facebook, если идентификатор пользователя отсутствует в запросе
if (пусто ($ fbData [«user_id»])) {
$ auth_url = «https://www.facebook.com/dialog/oauth?client_id=»
, $ config [«facebook»] [«appId»]. «& redirect_uri =». UrlEncode ($ конфиг [ «приложение»] [ «домой»])
, «& Сфера = электронная почта»;
echo ‘<script> top.location.href = «‘. $ auth_url. ‘»; </ script>’;
выход;
}
}

if ($ fbAccessToken = $ app-> Facebook-> getAccessToken ()) {
// если код присутствует, он был отправлен по запросу авторизации, поэтому перенаправьте обратно на страницу приложения Facebook
if ($ code = $ app-> request () -> get («code»)) {
$ App-> редирект ($ конфиг [ ‘facebook’] [ «canvas_url»]);
}
$ user = $ app-> Facebook-> getUser ();
if ($ user) {
пытаться {
// продолжить, зная, что у вас есть авторизованный пользователь, который аутентифицирован
$ app-> facebookUserProfile = $ app-> Facebook-> api («/ me»);
$ app-> facebookUserProfile [«logout»] = $ app-> Facebook-> getLogoutUrl ();
}
catch (FacebookApiException $ e) {
$ app-> flashNow («error», $ e-> getMessage ());
$ user = null;
}
}
}
}

[/исходный код]

Если приложение авторизовано для просмотра данных пользователя, оно проверяет параметр кода, переданный службой OAuth Facebook после успешной авторизации. Служба перенаправляет пользователя на URL-адрес приложения за пределами iframe, поэтому я решил перенаправить обратно на версию в рамке. В строке запроса передаются различные параметры, если по какой-то причине в авторизации отказано, но я игнорирую их в этой статье.

Затем код запрашивает профиль пользователя с помощью API Facebook, который сохраняется в свойстве $ app-> facebookUserProfile.

Но когда именно весь этот код выполняется? Я немного отредактировал код маршрутизации основных URL-адресов, чтобы учесть это:
[sourcecode language = ”php”]
<? PHP
$ app-> map («/», «facebookInit», function () use ($ app, $ config) {
// другой код здесь
}) -> via («GET», «POST»);

[/исходный код]

В терминологии Слима это называется Middleware. Функция facebookInit () вызывается перед анонимной функцией, которая обрабатывает маршрут. Используя эту функцию, каждая страница может получить доступ и использовать данные Facebook.

Резюме

В этой статье я показал вам пример простого приложения, созданного с использованием Heroku, Facebook SDK и других бесплатных компонентов. Я надеюсь, что это стимулировало ваше любопытство и ваше желание создать ваше следующее приложение в облаке Heroku. Вы можете найти полный исходный код приложения в учетной записи GitHub CloudSpring, если хотите клонировать его и изучить. Удачного кодирования!