Имея минимальный «реальный» опыт программирования, я работаю над проектом, который интегрирует решение FileMaker Pro, которое я уже построил, с нативным приложением iOS, использующим PHP API FileMaker Server. Приложение для iOS для iPhone и написано на Swift.
Мы пытаемся понять наиболее эффективные способы подхода к некоторым сценариям, особенно при записи данных обратно на сервер. Давайте использовать простой пример адресной книги. Когда пользователь переходит к записи контакта, он / она может выбрать поле, отредактировать и сохранить его содержимое.
Хотя мы уже реализовали ряд функций, которые записывают данные на сервер, все они были относительно простыми (например, сканирование штрих-кода, отправка запроса php, который запускает скрипт на FM-сервере, а затем представление результата клиенту). Кажется, что в случае записи контакта со многими полями отправка значения каждого поля в виде переменной, некоторые из которых могут быть абзацами или фотографиями, через стандартный URL-адрес PHP неэффективна и громоздка.
Для тех, кто не знаком с FileMaker PHP API, ниже приведен пример кода, демонстрирующий процесс обновления определенной записи контакта. Пример кода выполняет следующие действия:
Образец кода:
<?php
require_once 'Filemaker.php';
//connect to db
$fm = new FileMaker();
$fm->setProperty('database', 'fmDbName');
$fm->setProperty('hostspec', '123.45.67.89');
$fm->setProperty('username', 'user');
$fm->setProperty('password', 'password');
//define layout on which to process
$layout = 'php_contacts';
//define variables passed from client
$contactId = $_GET['contactId'];
$first = $_GET['firstName'];
$last = $_GET['lastName'];
$mobile = $_GET['mobile'];
$office = $_GET['office'];
$note = $_GET['note'];
//Find the contact which is being updated
$find = $fm->newFindCommand($layout);
$find->addFindCriterion('contactId', $contactId);
//execute the find
$results = $find->execute();
//check for error
if (FileMaker::isError($result)) {
echo " Error: ".$results." ";
exit;
}
//declare the record being updated
$record = $results->getFirstRecord();
//update the fields
$record->setField('firstName', $first);
$record->setField('lastName', $last);
$record->setField('mobile', $mobile);
$record->setField('office', $office);
$record->setField('note', $note);
?>
Задача, с которой мы сталкиваемся, не как Чтобы реализовать конкретный подход, скорее, проблема заключается в понимании того, какие варианты стоят на первом месте, и любых лучших практик, которые сопровождают их.
Например, лучше ли отправлять переменные из клиента в PHP в виде массива или словаря, чем отправлять их в виде независимых переменных в URL? Какие еще есть варианты для аккуратной отправки данных из нескольких полей в нативном приложении на сервер PHP?
Спасибо!
Так что есть пара вещей, которые вы могли или должны сделать.
Переместите информацию о соединении с вашей базой данных из вашего php-кода в сохраненный файл конфигурации вне корня документа сервера, т.е. если ваш корень документа находится по адресу:
/var/www/myapp/public/
Вы можете сохранить свой файл конфигурации по адресу:
/var/www/myapp/config/
Таким образом, если php каким-то образом завершится неудачно и вернется в виде текста против php-кода, ваши учетные данные не будут предоставлены. Вы можете сделать это разными способами, но самое простое, что я видел, это определить их как константы. например.:
// File config.php
define('FM_DATABASE', 'fmdbname');
define('FM_HOSTSPEC', '123.45.67.89');
define('FM_USERNAME', 'user');
define('FM_PASSWORD', 'password);
и потребуйте файл конфигурации в вашем коде и используйте константы в вашем объекте соединения:
$fm = new FileMaker(FM_DATABASE, FM_HOSTSPEC, FM_USERNAME, FM_PASSWORD);
Вы не делаете это в своем коде, но хорошо знать, имеете ли вы дело с PHP FileMaker API. Объект Error Result, который возвращается, если вы столкнулись с препятствием будет содержать ваши учетные данные подключения. Я понятия не имею, почему это так, но это так. Никогда не выгружайте весь объект клиенту, потому что вы будете предоставлять эти учетные данные как часть дампа.
Объект ошибки FileMaker расширяет Груша Ошибка Объект, поэтому, если вы захотите передать информацию об обнаруженной ошибке, вы можете использовать любой из методов груши.
Код FileMaker API устарел, когда дело доходит до php. статический метод FileMaker::isError
на самом деле не определяется как статический в коде API. Это означает, что если вы не подавите устаревшие сообщения на своем веб-сервере, веб-сервер будет лаять на вас. Дело в том, что вы уже создали экземпляр объекта FileMaker, так что вы можете использовать его, чтобы проверить, является ли ваш результат ошибкой:
if($fm->isError($result)){ // this won't produce the deprecated warning.
...
Тем не менее, вы, вероятно, увидите кучу других ошибок из-за другого устаревшего кода в API: P
Прямо сейчас вы выполняете поиск записи, обновляете ее поля и фиксируете ее. Это эмулирует работу с FileMaker, но, поскольку вы редактируете данные через интерфейс php, вы можете немного их сократить.
Если ваше клиентское приложение (приложение swift) уже знает идентификатор записи, которую он обновляет, вы можете использовать newEditCommand
вместо этого обновить запись. Команда редактирования использует FileMaker внутренний идентификатор записи (т. е. идентификатор, который FileMaker предоставляет записи, а не идентификатор из добавленного пользователем первичного ключа), чтобы определить, какую запись необходимо обновить. Вот пример того, как вы бы это использовали:
$editQuery = $fm->newEditCommand('my_layout', $recordId);
$editQuery->setField('Status', $newStatus);
$editResult = $editQuery->execute();
Преимущество этого заключается в меньшем времени обработки для FileMaker Server. Вы не просите сервер найти запись, чтобы вы могли редактировать ее, вы указываете, какую запись редактировать.
В зависимости от того, как бизнес-логика протекает через ваши приложения, это может быть не вариант, но если вы можете сохранить идентификатор записи на стороне клиента, это может помочь сделать связь немного более быстрой.
Похоже, вы уже делаете это, но не забудьте отправить данные в пакете по одному полю за раз. Я бы согласился с комментариями Arcrammer об использовании POST вместо GET, поскольку POST — это метод, предназначенный для отправки данных на сервер.
Это мои предложения по вашему коду. Я бы также предложил покопаться в коде API. Я обнаружил, что просмотр объектов и методов позволил мне ответить на множество вопросов, которых не было в документации и руководствах, которые FileMaker предоставляет для API.
Удачи!
$_GET
намного медленнее, чем $_POST
из моего понимания. Вы должны отправлять POST-запросы на сервер из вашего приложения, которое будет передавать строки. Отправка необработанных изображений через Интернет может легко привести к искажению и отсутствию данных. Для отправки изображений в виде строк вы должны использовать кодировку Base-64. Это означает, что вы преобразуете двоичный файл изображения в схему кодирования, которая возвращает строку. Вы можете отправить эту строку на сервер или в приложение для декодирования. (Примечание. Вы можете использовать изображения в кодировке Base-64 в качестве URL-адресов, что может пригодиться.)
Я не верю, что есть лучший способ отправки данных между сервером и клиентом, кроме использования сообщения POST или необработанного JSON, если вы можете это сделать. Swift и Objective-C имеют класс с именем NSJSONSerialization
который вы можете использовать для преобразования JSON, возвращенного из PHP-скрипта, для последующего использования в вашем приложении.
С вашего сервера вы можете просто создать пустой массив в переменной в начале скрипта для последующего использования, а затем добавить информацию в этот массив, когда он станет доступным (если у вас есть изображение на вашем сервере, вам нужно кодировать Base-64 затем он добавляет строку в массив только после завершения кодирования Base-64). В конце сценария — когда у вас есть все данные, которые вы хотите отправить в приложение, добавленное в этот массив — вы можете написать echo json_encode($thatArray)
отправить массив обратно в приложение как JSON. Конечно, это означает, что вы захотите, чтобы это был ассоциативный массив с самого начала, потому что у вас будут пары ключ и значение.
Я бы положился на этот метод для получения информации с сервера и перевернуть ее (создать Dictionary
в приложении Swift, затем используйте NSJSONSerialization.JSONObjectWithData(data: NSData, options: NSJSONReadingOptions, error: NSErrorPointer)
преобразовать Dictionary
в JSON. Затем создайте запрос, который отправит этот JSON на сервер через запрос POST. Конечно, ваш скрипт PHP будет использовать json_decode($_POST['thatJSONFromTheApplication'])
) для приложения, чтобы отправить JSON на сервер.
Это то, что я сделал, чтобы мое приложение и сервер работали вместе. Если вы читаете это, и у вас есть идея получше, делитесь!
Я уверен, что PHP в основном работает с HTTP-запросами, то есть POST и GET.
Структуры, которые вы отправляете, должны определяться тем, что вам нужно, идеального решения не существует.
Вы должны проверить, как работают HTTP-запросы:
http://www.w3schools.com/tags/ref_httpmethods.asp