凭借最少的“真实”编程经验,我正在开发一个项目,该项目将我已经构建的FileMaker Pro解决方案与使用FileMaker Server的PHP API的本机iOS应用程序集成在一起。 iOS应用程序适用于iPhone,使用Swift编写。
我们正在尝试了解处理某些方案的最有效方法,尤其是将数据写回服务器。让我们使用地址簿的简单示例。当用户导航到联系人记录时,他/她可以选择一个字段,编辑然后保存它的内容。
虽然我们已经实现了许多将数据写入服务器的功能,但它们都相对简单(比如扫描条形码,发送一个在FM Server中触发脚本的php请求,然后将结果呈现给客户端) )。在具有许多字段的联系人记录的情况下,似乎将每个字段的值作为变量发送,其中一些可能是段落或照片,通过标准的PHP URL低效且笨重。
对于那些不熟悉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服务器?
谢谢!
答案 0 :(得分:2)
$_GET
比$_POST
慢得多。您应该从您的应用程序向服务器发送POST请求,这将传输字符串。通过Internet发送原始图像很容易导致失真和丢失数据。要将图像作为字符串发送,您将使用Base-64编码。这意味着您将图像二进制文件转换为返回字符串的编码方案。您可以将此字符串发送到服务器或应用程序进行解码。 (注意:您可以使用Base-64编码图像作为URL,这可能会派上用场。)
我不相信除了使用POST消息或原始JSON(如果可以的话)之外,还有更好的方法在服务器和客户端之间发送数据。 Swift和Objective-C有一个名为NSJSONSerialization
的类,您可以使用它来转换从PHP脚本返回的JSON,以便稍后在您的应用程序中使用。
从服务器中,您只需在脚本开头的变量中创建一个空数组供以后使用,然后在该数组可用时将信息附加到该数组(如果您的服务器上有图像,则需要基础-64对其进行编码,然后仅在Base-64编码完成后将字符串附加到数组中)。在脚本结束时 - 当您拥有要发送到附加到该阵列的应用程序的所有数据时 - 您可以编写echo json_encode($thatArray)
以将数组作为JSON发送回应用程序。当然,这意味着你从一开始就希望它成为一个关联数组,因为你将拥有键和值对。
我依靠该方法从服务器获取信息并将其翻转(在Swift应用程序中创建Dictionary
,然后使用NSJSONSerialization.JSONObjectWithData(data: NSData, options: NSJSONReadingOptions, error: NSErrorPointer)
将Dictionary
转换为JSON。然后创建一个请求,通过POST请求将该JSON发送到服务器。当然,您的PHP脚本将使用json_decode($_POST['thatJSONFromTheApplication'])
)让应用程序将JSON发送到服务器。
这就是我为了让我的应用程序和服务器一起工作而做的。如果您阅读此内容并且有更好的主意,请分享!
答案 1 :(得分:1)
我非常确定PHP基本上可以处理HTTP请求,基本上是POST和GET。
您发送的结构应根据您的需要进行定义,没有完美的解决方案。
您应该检查HTTP请求的工作方式: http://www.w3schools.com/tags/ref_httpmethods.asp
答案 2 :(得分:1)
所以你可以或应该做的事情有很多。
将您的数据库连接信息从您的php代码移出到服务器文档根目录外部的配置文件中,即如果您的doc root位于:
/var/www/myapp/public/
您可以将配置文件存储在:
/var/www/myapp/config/
这样一来,如果php以某种方式失败并以文本和PHP代码的形式返回,那么您的凭据就不会公开。你可以通过多种方式实现这一点,但我见过的最简单的方法是将它们定义为常量。 e.g:
// 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);
您不是在代码中执行此操作,但了解您是否正在处理FileMaker PHP API是一件好事。如果遇到障碍,则返回的错误结果对象将包含您的连接凭据。我不知道为什么会这样,但事实确实如此。永远不要将整个对象转储到客户端,因为您将作为转储的一部分公开这些凭据。
FileMaker的Error对象扩展了Pear Error Object,因此如果您想要传回有关遇到的错误的信息,可以使用任何pear error方法。
关于php,FileMaker API代码已经过时了。静态方法FileMaker::isError
实际上未在API代码中定义为静态。这意味着除非您在Web服务器上压缩已弃用的消息,否则您将让Web服务器对您咆哮。问题是,您已经创建了FileMaker对象的实例,因此您可以使用它来检查结果是否是错误:
if($fm->isError($result)){ // this won't produce the deprecated warning.
...
那就是说,由于api中其他已弃用的代码,你可能会看到一堆其他错误:P
现在,您正在为记录执行查找,更新其字段并进行提交。这模拟了FileMaker的体验,但是因为你是通过php界面编辑数据的,所以你可以稍微缩短一下。
如果您的客户端应用程序(swift应用程序)知道它已经更新的记录的记录ID,那么您可以使用newEditCommand
来更新记录。 edit命令使用FileMaker 内部记录ID(即FileMaker提供记录的ID,而不是用户添加的主键的id)来确定要更新的记录。以下是您如何使用它的示例:
$editQuery = $fm->newEditCommand('my_layout', $recordId);
$editQuery->setField('Status', $newStatus);
$editResult = $editQuery->execute();
这样做的好处是减少了FileMaker Server的处理时间。您不是要求服务器找到记录以便您可以编辑它,而是告诉它要编辑哪条记录。
根据业务逻辑如何流经您的应用程序,这可能不是一种选择,但如果您可以在客户端存储记录ID,则可能有助于使通信更加快捷。
看起来您已经这样做了,但请务必一次发送批量与一个字段的数据。我同意Arcrammer关于使用POST而不是GET的评论,因为POST是将数据发送到服务器的预期方法。
这些是我对您的代码的建议。我还建议在API代码中进行挖掘。我发现查看对象并且方法为我回答了很多问题,FileMaker为API提供的文档和教程没有。
祝你好运!