I've got an iOS and Android app which downloads data from a database using JSON and PHP. Basically its a lot of mysql queries which returns data from my MySQL database. When I started this project is just created an array in php which holds all queries. Then I would send an index in my url to access that query and optionally some variables.
http://url.nl/script.php?index=1&var1=foo&var2bar
This worked fine and for a small project it wasn't bad but I knew this isn't good programming nor a good model.
So basically it's something like this:
APP with Model-View-Controller-Store model
When app needs data, Store classes request data through url and also send an index in that url
PHP script reads index, executes saved query in array, encodes data to JSON, returns data
App's store classes read and decode data
App's View classes present the data in any way wanted.
So I'm not really doing much with php other than accessing my database, encoding and returning data.
Since my app is getting very large and using more and more queries I wanted to do things right in my new version. What would be a good model for PHP to use in this scenario?
I'm no web developer so I was trying to keep all PHP processes to a minimum but realized this isn't a good way of programming.
Instead of just storing your queries in an array, you should instead use some kind of RESTful API on your server.
You then would send GET requests to your server, which executes them and returns the desired data. This could then be read and decoded. (You can also send and update data to the server).
There are a bunch of REST Framworks for PHP, but i used "Slim Framework" because its really easy to understand (even for people not familiar with php).
This Example from their Website:
$app = new \Slim\Slim();
$app->get('/hello/:name', function ($name) {
echo "Hello, $name";
});
$app->run();
makes it possible to call www.yourside.com/hello/Mark, which then returns "Hello Mark". With 5 lines of code. Its awesome.
You can write any php code there. To encode your data from a MySQL Database just follow this Tutorial: http://coenraets.org/blog/2011/12/restful-services-with-jquery-php-and-the-slim-framework/ Just ignore the JQuery part.
In your App you then request the Data from the provided URL. I use AFNetworking for this. (Google it, on their page find "HTTP Request Operation Manager" and look at GET)
Related
I have location data containing lat,long,location_name to be shown in the map. Only logged in users can see this map. What I did was that I used php and with a select * to MySQL DB and then I used json_encode to format the data in usable way and echoed it to be grabbed in the front-end and used in map api. This php file echoing the JSON file is called mapData.php
I want this file to not be accessible even from logged user. I came across session and request headers in the mapData.php file (internal api file)but then again if h hacker sign up to my service and open dev console he/she can see the received file and with one side requesting tool can put the header and see the data. Or maybe changing the access level with Linux but I have no idea how.
Another method is uglify and minifying JSON but since I am having 29000 rows in my dB with another inner join I think it will slow down the process. Any suggestion for securing this internal api so that even logged in user cannot access to it?
I would hide the map data file in a subdirectory, then use a service to access the data file and retrieve just the data you need. If you absolutely need the 29,000 rows at once, then there's not much you can do. Even if you encrypt it, eventually the data is going to be in native JavaScript format, and then it's just a matter of running a debugger and peering in the data structures.
Say I have a php file on my web server which contains a class 'Database'. Inside that class is a public function, lets call it 'data_select', which queries MySql database:
public function data_select($query) {
...
return $rows;
How would I pass in the '$query' parameter to this function from a Swift iOS application?
There are a number of answers online regarding $_POST from swift, but these often concern SQL queries such as 'INSERT INTO ...', whereas my case is a 'SELECT...' query. I also cannot seem to find anything regarding triggering class functions from Swift, although I know it must be possible.
Have I got the wrong idea here? I understand how to pull data from a php file on web server when the sql query and everything is included in the same file, but here the parameters of the query can differ, thus I have the basic SELECT query as part of a database class which can be called with different parameters on my test website, but I cannot work out how to pass in the query parameter from swift and trigger the function.
I guess I could trigger the functions by making a call to a different php file containing an instance of the function with the $query parameter passed in from swift. But would I then need to create multiple php files for each different 'SELECT...' query which sort of defeats the point of having the functions in a class???
PHP is scripting language, mainly used as a server side web language. Swift can communicate with any server side language that uses HTTP. You can use any of the HTTP verbs such as GET, POST, PUT etc to send and receive data from PHP using Swift.
So you'd want to create an endpoint with PHP. You can make an NSMutableURLRequestin swift to send data as a URL parameter.
Take a look at this link to make a GET request in swift.
And take a look at this link to handle a GET request in PHP.
For the multiple files part of your question, you could put many of these endpoints all within one file but that is an implementation and design choice that depends on how you want your application and server to flow.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
With minimal "real" programming experience, I am working on a project that integrates a FileMaker Pro solution, which I have already built, with a native iOS application using FileMaker Server's PHP API. The iOS application is for iPhone and is written in Swift.
We are trying to understand the most efficient ways to approach some scenarios, particularly in writing data back to the server. Let's use the simple example of an address book. When a user navigates to a contact record, he/she can select a field, edit then save it's contents.
While we have already implemented a number of functions that write data to the server, they have all been relatively simple (like scanning a barcode, sending a php request that triggers a script in FM Server and then presenting the result to the client). It seems like, in the case of a contact record with many fields, that sending the value of each field as a variable, some of which may be paragraphs or photos, through a standard PHP URL inefficient and bulky.
For those unfamiliar with the FileMaker PHP API, below is some sample code to demonstrate the process of updating a specific contact record. The sample code does the following:
Sets parameters passed from the client as variables.
Defines the layout on which the code should be executed (FM PHP API works on layouts, not tables like SQL)
Finds a record and updates the fields.
Sample Code:
<?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);
?>
The challenge we are facing is not how to implement a particular approach, rather, the challenge is understanding what the options are in the first place and any best practices that go along with them.
For example, is sending the variables from the client to PHP as an array or dictionary a better practice than sending them as independent variables in the URL? What are some other options for neatly pushing data from multiple fields in a native application to the PHP server?
Thanks!
I'm pretty sure PHP basically works with HTTP requests, that is basically POST and GET.
The structures you send should be defined by what you need, there is no perfect solution.
You should check how HTTP requests work:
http://www.w3schools.com/tags/ref_httpmethods.asp
$_GET is much slower than $_POST from my understanding. You should send POST requests to the server from your application which will transfer strings. Sending raw images over the Internet can easily lead to distortion and missing data. In order to send images as strings you would use Base-64 encoding. That means you'll convert the image binary to an encoding scheme which returns a string. You can send this string to the server or the application for decoding. (Note: You can use Base-64 encoded images as URLs, which may come in handy.)
I don't believe there's a better way to send data between a server and client aside from using either a POST message or raw JSON if you can do that. Swift and Objective-C have a class named NSJSONSerialization which you can use to convert JSON returned from a PHP script for use later in your application.
From your server you can simply create an empty array in a variable at the beginning of the script for later use then append information to that array as it becomes available (If you have an image on your server you'll want to Base-64 encode it then append the string to the array only after the Base-64 encoding completes). At the end of the script -- when you have all of the data you want to send to the application appended to that array -- you can write echo json_encode($thatArray) to send the array back to the application as JSON. Of course, that means you'll want this to be an associative array from the beginning, because you'll have key and value pairs.
I'd rely on that method to fetch information from the server and flip it around (create a Dictionary in the Swift application then use NSJSONSerialization.JSONObjectWithData(data: NSData, options: NSJSONReadingOptions, error: NSErrorPointer) to convert the Dictionary to JSON. Then create a request which will send that JSON to the server via a POST request. Of course, your PHP script would use json_decode($_POST['thatJSONFromTheApplication'])) for the application to send JSON to the server.
That's what I've done to allow my application and server to work together. If you read this and you have a better idea, do share!
So there are a couple of things you could or should do.
Should do:
Move credentials out of the document
Move your database connection information out of your php code and into a configuration file stored outside of the server document root, i.e. if your doc root is at:
/var/www/myapp/public/
You could store your configuration file at:
/var/www/myapp/config/
That way if php somehow fails and returns as text vs php code, your credentials are not exposed. You could do this in many ways, but the easiest I've seen is to define them as constants. e.g.:
// File config.php
define('FM_DATABASE', 'fmdbname');
define('FM_HOSTSPEC', '123.45.67.89');
define('FM_USERNAME', 'user');
define('FM_PASSWORD', 'password);
and require the config file in your code and use the constants in your connection object:
$fm = new FileMaker(FM_DATABASE, FM_HOSTSPEC, FM_USERNAME, FM_PASSWORD);
Never dump the entire result if it's an error
You're not doing this in your code, but it's a good thing to know if you're dealing with the FileMaker PHP API. The Error Result object that is returned if your runs into a snag will contain your connection credentials. I have no idea why this is so, but it is. Never dump the entire object to the client because you'll be exposing those credentials as part of the dump.
FileMaker's Error object extends the Pear Error Object, so if you end up wanting to pass back information on an error that was encountered you can use any of the pear error methods.
Use the connection object to test for errors
The FileMaker API code is pretty out of date when it comes to php. the static method FileMaker::isError is actually not defined as static in the API code. This means unless you supress the deprecated messages on your web server you'll have the web server barking at you about it. The thing is, you've already created an instance of the FileMaker object so you can use it to check if your result is an error:
if($fm->isError($result)){ // this won't produce the deprecated warning.
...
That said, you'll probably see a bunch of other errors because of other deprecated code in the api :P
Could do:
Cache the record id in your client app
Right now you're performing a find for a record, updating it's fields, and committing it. This emulates the FileMaker experience, but because you're editing the data via the php interface you may be able to short cut it a bit.
If your client application (the swift app) knows the record id for the record that it's updating already then you could use the newEditCommand to update the record instead. The edit command uses the FileMaker internal record id (i.e. the id that FileMaker gives the record, not the id from your user-added primary key) to determine which record to update. Here's an example of how you'd use it:
$editQuery = $fm->newEditCommand('my_layout', $recordId);
$editQuery->setField('Status', $newStatus);
$editResult = $editQuery->execute();
The advantage of doing this is less processing time for FileMaker Server. You're not asking the server to find the record so you can edit it, you're telling it what record to edit.
Depending on how the business logic flows through your apps this may not be an option, but if you could store the record id on the client side it may help make the communication a bit snappier.
Handle the updates in batches
It looks like you're already doing this, but be sure to send the data in a batch vs one field at a time. I would agree with Arcrammer's comments about using POST instead of GET as POST is the intended method for sending data to the server.
Those are my suggestions on your code. I would also suggest digging around in the API code. I find that looking over the objects and there methods answered a lot of questions for me that the documentation and tutorials that FileMaker provides for the API did not.
Good luck!
I am writing an Android App, and already have a working program written in HTML and PHP. Using the two, they contact an API with a user customized lookup on the html page, which then sends to the PHP page, contacts the API with the customized search, gets a result, and the php outputs to a html page again.
I know PHP cannot work on Android, but I plan on using PhoneGap. With PhoneGap, I can run JavaScript, HTML, and CSS supposedly. I have also read that a solution with Android being unable to understand PHP is to connect to a server (my computer) which can run the php for me, and then output it in a way the phone can understand.
My plan is to use JavaScript, which PhoneGap can understand, to connect to my computer, and have it run the PHP and output the page in HTML which again, PhoneGap can understand.
If this is absurd, please let me know... Otherwise I'd greatly appreciate it if someone could push me in the right direction in a JavaScript function that would allow me to authenticate myself, connect to my computer, and tell it I'd like to use a certain PHP file.
We had the exact same problem when developing our application for Android as well as for iOS. Like Austin told you already you have to make use of AJAX.
W3schools - AJAX
I recommend you however not to use jquery if it's only needed for a few simple things because it's fairly heavy because of the big script it has to load. So if you can reduce the amount of code, please do so by learning the real JavaScript instead of jQuery.
Also, what we did is writing our own APIRequest.js object. When calling this object like so:
var result = new APIRequest('functionname', {param1:value, param2:value})
This is a fairly easy approach to connect to your php which will run off course on your server somewhere in a foreign country or your pc.
As you can see we insert a functionname, we have developed our API as a fairly simple OOP php thingy that allows us to put a functionname.php in a certain folder and it will be read by de script and then select that function. Database connections and stuff like that will be aranged in the index of the api. With this approach you can make special functions, server-side, for every unique handling.
I am telling you this because you are making use of JavaScript. I'd like you to understand that it is not safe! It as as safe as a JavaScript application on your computer. It is possible for a hacker to download the .apk to his computer, run it in the simulator on his pc and make edits through his console. And thus meaning, he can change your whole code (at least, the JavaScript part). So make sure you try to make this as safe a possible, with keys and stuff like that. Also, try to do as much logic as possible on your server, so the logic can't be changed. Only the input parameters to your API.
I hope this helped you!
Here you would need to use AJAX. jQuery has a great wrapper function called $.ajax that makes most of the process pretty simple and straightforward.
AJAX will send an asynchronous request to any file (in your case a php file) and fire a callback function with the data it receives.
(synchronous is also possible, but not recommended as it will make your application hang until the request is complete. More on why this is not recommended)
Some good reads on the subjects covered here:
http://www.sitepoint.com/ajax-jquery/
http://www.impressivewebs.com/callback-functions-javascript/
The basic technology you want to use is AJAX, which is the term for making server calls over HTTP from Javascript. You pass data to and from the server in XML (the X in AJAX) or perhaps in another encoding, such as JSON.
You'll need a dedicated PHP file on the server that will understand the data you send in the AJAX post and instead of generating HTML generates the XML/other format your Javascript will consume.
Your best bet would probably be to create a browser app that communicates with your server via AJAX, and when that is working port it to PhoneGap.
It's very easy. Just do a GET request to the PHP page and parse the result. Create a function to make it easier:
function httpGet(theUrl){
var xmlHttp = null;
xmlHttp = new XMLHttpRequest();
xmlHttp.open( "GET", theUrl, false );
xmlHttp.send( null );
return xmlHttp.responseText;
}
Then, you can call it and obtain the resultant HTML code.
var url = 'http://yourpage/index.php?a=something&b=otherthing';
var page = httpGet(url);
new to dojo and javascript in general. I'm working with a piece of code that requires a button to be different depending on what a php database query returns. The php script is already written, and the code I have currently is:
var store = new SimpleSaveWriteStore( {url: "info_get.php"} );
info_get.php returns the data as a JSON object, but what is the syntax to access the data members inside store? I've searched for this but there isn't a whole lot of documentation I've found on SimpleSaveWriteStore.
TL;DR - how would I access a specific piece of data retrieved in the above code? Thanks!
SimpleSaveWriteStore isn't a part of Dojo, so I am going to assume that this is this where you got the code from:
http://kennethfranqueiro.com/2010/06/custom-save-logic-itemfilewritestore/
This code extends the dojo.data.ItemFileWriteStore, and you can query against the store.
http://dojotoolkit.org/reference-guide/1.7/dojo/data/ItemFileReadStore.html#query-syntax
A couple things to note. Dojo is moving toward dojo.store api instead of the dojo.data api (which is the the ItemFileRead and ItemFileWrite store). The dojo store api documentation can be found at:
http://dojotoolkit.org/reference-guide/1.7/dojo/store.html
Also, if the data that you are getting back from the php script, is very simple, a store might not even be needed. You could use dojo.xhr to make the request and get json data. Then just use the json data to get the value that you need. The data and the store api use dojo.xhr to get the data. The documentation for dojo.xhrGet can be found at
http://dojotoolkit.org/reference-guide/1.7/dojo/xhrGet.html