Applying PHP in XOJO to connect to MySQL database

Hi all,

I have some issue with connecting to a MySQL database hosted by our service provider (http://www.123-reg.co.uk/ ). When I contacted them this was their response:

Unfortunately a remote connection it’s not supported with our hosting packages.
However you can try to connect to your database using the steps below:
http://www.123-reg.co.uk/support/answers/Databases/Linux-MYSQL/how-do-i-connect-to-my-mysql-database-4178/

It basically proposes to use PHP to attempt a connection to the server choice. I’m attempting to put together the logic to do this but I’m struggling with applying PHP to the MySQL example that comes with XOJO. Is this possible and any ideas on how to go about this?

Just as a mention using the XOJO MySQL example I’ve successfully connected to a Google Cloud SQL database:

[code] mDb = New MySQLCommunityServer

mDb.Host = “ip address of the Google Cloud SQL db”
mDb.UserName = “root”
mDb.Password = “xxxxxxxxx”
mDb.DatabaseName = “test”

If mDb.Connect Then
mIsConnected = True
ConnectStatusLabel.Text = “Connected to MySQL”
Else
mIsConnected = False
ConnectStatusLabel.Text = "Error connecting to MySQL: " + mDb.ErrorMessage
End If
[/code]

Cheers for any help.

Alex.

This means you cannot connect directly to a mysql database running on their servers
Basically they have no open ports that it can use
And to be honest this is a good thing

Effectively you write a PHP app that runs on the hosting server
Then your Xojo app talks to that PHP app to do whatever it needs
Not the simplest thing to do if you don’t have experience writing PHP apps & Xojo apps

The google mysql test you did sure looks like a mysql database publicly exposed on the internet which carries certain security risks with it. Google for “mysql exploit” and you can find references to ones that have occurred in the past (not sure which ones are still open but a https://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=mysql will give you some idea)

Its why exposing most ANY database directly & publicly on the internet is risky & why you probably want some other software in between the DB and the internet

You will need to write a PHP script that queries MySQL and responds. You will need to talk to the PHP script via a HTTPSocket.

@Norman Palardy and @Phillip Zedalis: Thanks for the very helpful replies.

Indeed it seems a challenge to do the following:

  • Firstly write the PHP script to interact with MySQL database in the hosting provider’s server.
  • Then secondly write XOJO code to interact with the PHP script.

Regarding the 1st bit I found this link which on the server side utilises a PHP driver and a PHP database wrapper as part of the server side logic to get to the database. On their UI side they are utilising Javascript as seen in figure 1 in the link.

Something of note from the link is that they built a Javascript wrapper which interacts with a JQuery script which leads me to my question any examples/ideas on how I could get started on interaction between XOJO and PHP .

I’ll get on with looking around for a basics on how to undertake the above-mentioned challenges.

Regards,
Alex.

@Norman Palardy : Having thought through my earlier post further is to possible in XOJO interact with a Java database interaction program/wrapper which runs on the hosting server and which will query/interact with the MySQL database on the hosting server?

Another option would be to divide and conquer the writing of the PHP script to interact with MySQL database (in the hosting provider’s server) using the following breakdown from chapter 14 of the following PHP with MySQL Essential Training course on lynda.com:


Using PHP to Access MySQL
Database APIs in PHP
Connecting to MySQL with PHP
Retrieving data from MySQL
Working with retrieved data
Creating records with PHP
Updating and deleting records with PHP
SQL injection
Escaping strings for MySQL
Introducing prepared statements

Having realised what it takes to complete the above tasks I will definitely have to refresh my mind with regards to PHP which is what chapters 1 to 12 seem to do.

In mentioning the above do you feel there’s another way to breakdown and tackle the task of writing of the PHP script to interact with MySQL database (in the hosting provider’s server) ?

BTW I mentioned java in my earlier post as I’ve interacted with MySQL using a Java database wrapper class essentially a table manager which connects to a Google Cloud MySQL database which performs all the basic CRUD based tasks.

Cheers for any suggestions.

Since you’d have to write coms custom protocol anyways sure … you can do whatever you dream up

Hi all,

Having dug deeper as explained in my last post I’ve been able to learn the basics of how to connect to/interact with a MySQL database on my hosting providers server using a PHP script. To recap this thread I was having issues connecting to a MySQL database on my hosting providers server as they do not provide a remote connection which @Norman Palardy in an earlier post aided me in understanding as an intentional thing done by the provider through no open ports being provided.

Please see my code below in relation to establishing a basic connection with a MySQL database using a PHP script:

[code]<?php
// 1.Create a database connection
$dbhost = “mydbhostserver”; // 94.136.40.100
$dbuser = “uname”;
$dbpass = “password”;
$dbname = “dbname”;

$connection = mysqli_connect($dbhost, $dbuser, $dbpass, $dbname);

// Test if connection occured
if(mysqli_connect_errno()) {
die("Database connection failed: " .
mysqli_connect_error() .
“(” . mysqli_connect_errno() . “)”);
}

?>

Connecting to MySQL with PHP <?php // 5.Close a database connection mysql_close($connection); ?>[/code]

I have two things I’m unsure of how to go about and any suggestions are welcome:

  • Firstly (and i know this isn’t a PHP forum) using phpMyAdmin how does one go about uploading a PHP script?
  • Secondly any ideas regarding the interaction of the basic below XOJO code to a my above mentioned PHP script which will be executing the respective SQL.

[code] mDb = New MySQLCommunityServer

mDb.Host = “mydbhostserver”
mDb.UserName = “uname”
mDb.Password = “password”
mDb.DatabaseName = “dbname”

If mDb.Connect Then
mIsConnected = True
ConnectStatusLabel.Text = “Connected to MySQL”
Else
mIsConnected = False
ConnectStatusLabel.Text = "Error connecting to MySQL: " + mDb.ErrorMessage
End If
[/code]

Regarding my 2nd point it seems to me writing the output of the PHP script into a file and then having the Xojo code read the file is an could be a potential solution? Is this what’s going on here:

Any suggestions are appreciated.
Alex.

Hi all,

Having read a little bit more regarding my first point as per my last post i.e. going about uploading a PHP script using phpMyAdmin I realise this will be done in the specified web server’s root directory. How this is done in phpMyAdmin is what I need to keep researching on.

[quote=136270:@Alex Monari]Hi all,

Having dug deeper as explained in my last post I’ve been able to learn the basics of how to connect to/interact with a MySQL database on my hosting providers server using a PHP script. To recap this thread I was having issues connecting to a MySQL database on my hosting providers server as they do not provide a remote connection which @Norman Palardy in an earlier post aided me in understanding as an intentional thing done by the provider through no open ports being provided.

Please see my code below in relation to establishing a basic connection with a MySQL database using a PHP script:

[code]- Secondly any ideas regarding the interaction of the basic below XOJO code to a my above mentioned PHP script which will be executing the respective SQL.

[code] mDb = New MySQLCommunityServer

mDb.Host = “mydbhostserver”
mDb.UserName = “uname”
mDb.Password = “password”
mDb.DatabaseName = “dbname”

If mDb.Connect Then
mIsConnected = True
ConnectStatusLabel.Text = “Connected to MySQL”
Else
mIsConnected = False
ConnectStatusLabel.Text = "Error connecting to MySQL: " + mDb.ErrorMessage
End If
[/code]

Regarding my 2nd point it seems to me writing the output of the PHP script into a file and then having the Xojo code read the file is an could be a potential solution? Is this what’s going on here:

Any suggestions are appreciated.
Alex.[/quote]
For this you wouldn’t be using the MySQL plugins for Xojo, you would use a HTTPSocket to connect to your PHP script and the PHP handles all the MySQL things. Regarding your PHP, you probably don’t need full HTML responses since Xojo will be using the responses to handle appropriately.

You may want to consider adding an auth key for communications between your app and the script to help protect your script from malicious users interfacing with it directly.

I’m available for private consultation if you need a PHP/MySQL + Xojo person.

@ Tim Parnell: I truly appreciate your response as it seems to have opened up my mind regarding my starting direction wrt communication between the PHP script and XOJO. I’m considering your suggestion of a private consultation but firstly through the forums I would like to grasp the concepts of the HTTPSocket connection and authentication.

I spent a lot of time researching this and using PHP on the server and HTTP protocol is the prevailing way to do this.

Your Database is residing on a server and your PHP page or script is what will be interacting with your DB. Your Xojo application will use standard HTTP to talk to and request information from your PHP script. The PHP acts like a connector between your DB and your app.

Because of this you will want review the Xojo Docs on HTTP and POST. For example you might have your PHP interpret one parameter of the POST as a command to do something, such as write a record to the database, the other parameters being the data you want to write. Once received your PHP script would then parse the command and execute the code to write the passed parameters to the database. Another command may be to retrieve a specific record set and return the values for display in your Xojo APP.

Now, although your database is not out in the open on the net it does not mean this is secure. I’d solicit some feedback on this to ensure you are taking measures to ensure a higher level of security. For example (and I am open to more suggestions).

  1. You really should be using the SecureSocket and SSL to communicate with your PHP. The reason is the helps prevent a man in the middle from deciphering your traffic and sending bogus requests or commands to your page.
  2. Your PHP script should reject any connection that is not HTTPS.
  3. Be aware that error reporting from PHP can be quite verbose, therefore it can be used by hackers to determine what is expected. Personally I turn off all error reporting and if something doesn’t work, I just do nothing.
  4. You should develop some protocol that verifies that the commands sent to the PHP page came from your application and not someone’s web browser or another source. You don’t want someone to fill your database with a bunch of bogus data. This can be a complex generated encrypted string that decrypted by your PHP to authenticate the source.
  5. Personally I would not allow a record deletion, but only a flag to be set to be deleted in your database.
  6. Assume everything in your app can be decompiled and therefore any security features could be compromised so any of this should be obfuscated as much as possible.

I’m not a internet security expert by any stretch, I’m merely exchanging ideas, so I’m sure others have more or better ideas as well.

Hope this helps good luck.

If the database is located on the same server as your hosting account you should be able to write a Xojo web app that you can put on the server to interact with the database on the localhost. There’s no reason that you would specifically need PHP if it’s just a remote access issue because a PHP web app would still have the same remote access problem if it’s not hosted on the same localhost.

I think a Xojo web app would be overkill for this situation. Just because you have a hammer doesn’t mean everything around you is a nail.

As a user of both xojo and another basic program for android, they used this example to connect to a database.

<?

$databasehost = "localhost";
$databasename = "xxxx";
$databaseusername ="xxxx";
$databasepassword = "xxxx";

$con = mysql_connect($databasehost,$databaseusername,$databasepassword) or die(mysql_error());
mysql_select_db($databasename) or die(mysql_error());
mysql_query("SET CHARACTER SET utf8");
$query = file_get_contents("php://input");
$sth = mysql_query($query);

if (mysql_errno()) {
    header("HTTP/1.1 500 Internal Server Error");
    echo $query.'\
';
    echo mysql_error();
}
else
{
    $rows = array();
    while($r = mysql_fetch_assoc($sth)) {
        $rows[] = $r;
    }
    print json_encode($rows);
}
?>

Is was said the security was poor but maybe with https it might be ok.
Just my 2 australian cents worth.
Tom

That lets anyone run any kind of query they like on your database. Very bad idea.
There isn’t even any kind of basic authorization request, “poor security” doesn’t even come close :stuck_out_tongue:

I’d suggest creating a remote procedure call (RPC) server, there’s a good outline here that describes the request and response JSON objects.

You send a JSON object that encapsulates the data you want to insert / update / delete and direct it to the appropriate service / method on your RPC server. The database updates are then handled in PHP and a response JSON object is sent back to the client.

[quote=141662:@Steve Wilson]I’d suggest creating a remote procedure call (RPC) server, there’s a good outline here that describes the request and response JSON objects.

You send a JSON object that encapsulates the data you want to insert / update / delete and direct it to the appropriate service / method on your RPC server. The database updates are then handled in PHP and a response JSON object is sent back to the client.[/quote]
I’d do something as described in this article:
http://www.xdevmag.com/browse/12.5/12506/

Then, from your server app you can do and serve pretty much anything you like, without exposing your database server.

You don’t expose your database with an RPC server, and you can serve anything you like too either via your services and their methods or direct from the web server which is hosting the RPC server.

I’m not going to buy the magazine you linked to to see what the suggestion is but I doubt it’s a better solution than creating an RPC server in PHP which not only is the default programming language offered by most web hosts but also has a very rich variety of excellent database connectivity libraries as well as libraries for creating spreadsheets, PDFs, etc… Getting to know PHP is well worth while.

Here’s another advantage, I have this app on my Android phone which replicates a set up I have on my desktop. You see learning to create a PHP RPC server is not only useful in the context of deploying a web service, you can use it as a method for creating personal applications you want to be able to run on your smartphone as well as your desktop.

@Joseph Evert:

Thanks for the reply.

[quote]I spent a lot of time researching this and using PHP on the server and HTTP protocol is the prevailing way to do this.

Your Database is residing on a server and your PHP page or script is what will be interacting with your DB. Your Xojo application will use standard HTTP to talk to and request information from your PHP script. The PHP acts like a connector between your DB and your app.

Because of this you will want review the Xojo Docs on HTTP and POST. For example you might have your PHP interpret one parameter of the POST as a command to do something, such as write a record to the database, the other parameters being the data you want to write. Once received your PHP script would then parse the command and execute the code to write the passed parameters to the database. Another command may be to retrieve a specific record set and return the values for display in your Xojo APP.

Now, although your database is not out in the open on the net it does not mean this is secure. I’d solicit some feedback on this to ensure you are taking measures to ensure a higher level of security. For example (and I am open to more suggestions).

You really should be using the SecureSocket and SSL to communicate with your PHP. The reason is the helps prevent a man in the middle from deciphering your traffic and sending bogus requests or commands to your page.
[/quote]

Following up on the above section of your post and having gone through refreshing my mind regarding the execution of CRUD on a MySQL database I’ve got some code below which I use to read data from a table subjects.

manage_content.php:

<?php require_once("../includes/database_connection.php"); ?>
<?php require_once("../includes/functions.php"); ?>
<?php include("../includes/layouts/header.php"); ?>
<?php find_selected_page() ?>

    <div id="main">
      <div id="navigation">

      <ul class="subjects">
        <?php $subject_set = find_all_subjects(); ?>

        <?php
          // 3 .b. Open a while loop to use returned data if any available based on subjects query.
          while($subject = mysqli_fetch_assoc($subject_set)) {
        ?>
        
        <?php "<li class=\"selected\">" ; ?>

          <?php // When assigning the value of <a href page using PHP page you pass the specific page id/DB value as you did in lesson 17- Using Site Navigation to Choose Content?>
          <a href="manage_content.php?subject=<?php echo urlencode($subject["id"]); ?>"><?php echo $subject["menu_name"]; ?></a>

          <?php $page_set = find_pages_for_subject($subject["id"]); ?>

          <ul class="pages">
 
            <?php
            // 3 .b. Open a 1ST NESTED while loop to use returned data if any available based on pages query.
              while($page = mysqli_fetch_assoc($page_set)) {
            ?>
            
            <li><a href="manage_content.php?page=<?php echo urlencode($page["id"]); ?>"><?php echo $page["menu_name"]; ?></a></li>         

            <?php } ?>

            <?php mysqli_free_result($page_set); ?>            
          </ul>
        </li>

        <?php } ?>

        <?php mysqli_free_result($subject_set); ?>
      </ul>

      </div>

    </div>

    <br/>
    <a href="new_subject.php">+ Add a subject </a>

    <div id="page">
      <h2>Manage Content</h2>

      <?php if($current_subject) { ?>
        <?php echo "Menu name in the associative array $current_subject is: " . $current_subject["menu_name"]; ?></br>
      <?php } elseif($current_page) { ?>
        <?php echo "Menu name in the associative array $current_page is: " . $current_page["menu_name"]; ?></br>
      <?php } else { ?>
        <?php echo "NO SELECTION MADE"; ?>
      <?php } ?>

    </div>

<?php include("../includes/layouts/footer.php"); ?>

functions.php:

<?php 

	function redirect_to($new_location) {
		header("Location: " . $new_location);
		exit;
	}

	function confirm_query($result_set) {
	  // Test for query error
	  if (!$result_set) {
	    die("DB SELECT * query failed");
	  } else {
	    //echo "<br />";
	    //echo "DB SELECT * query successful";  
	    //echo "Returned result is: " . $result;
	  }
	}

	function find_all_subjects() {
	  global $connection;

	  // 2. Perform subjects database query
      $query = "SELECT * ";
      $query .= "FROM subjects ";
      $query .= "WHERE visible = 1 ";
      $query .= "ORDER BY position ASC";

      // Contains reuslt in relation to selection of subjects. This variable should not be re-populated further down 
      // WRT using another mysqli_query() function
      $subject_set = mysqli_query($connection, $query);

      confirm_query($subject_set);

      return $subject_set;
	}

	function find_pages_for_subject($subject_id) {
	  global $connection;

	  // The subject ID has been escaped so to counter SQL injection
      $safe_page_id = mysqli_real_escape_string($connection, $subject_id);

	  // 2. Perform database query to find out which pages belong to the subjects we intend on displaying
	  $query = "SELECT * ";
	  $query .= "FROM pages ";
	  $query .= "WHERE visible = 1 ";
	  $query .= "AND subject_id = {$safe_page_id} ";            
	  $query .= "ORDER BY position ASC";

      // The subject ID has been escaped so to counter SQL injection
      $safe_subject_id = mysqli_real_escape_string($connection, $subject_id);
	  $page_set = mysqli_query($connection, $query);

	  confirm_query($page_set);

      return $page_set;
	}

	function find_subject_by_id($subject_id) {
	  global $connection;
	  
	  // The subject ID has been escaped so to counter SQL injection
      $safe_subject_id = mysqli_real_escape_string($connection, $subject_id);

	  // 2. Perform subjects database query
      $query = "SELECT * ";
      $query .= "FROM subjects ";
      $query .= "WHERE id = {$safe_subject_id} ";
      $query .= "LIMIT 1";

      // Contains reuslt in relation to selection of subjects. This variable should not be re-populated further down 
      // WRT using another mysqli_query() function
      $subject_set = mysqli_query($connection, $query);

      confirm_query($subject_set);

      // Return an associative array containing the result set data from the execution of the above query
      if($subject = mysqli_fetch_assoc($subject_set)) {
	    return $subject;
	  } else {
	  	return null;
	  }
	}

	function find_page_by_id($page_id) {
	  global $connection;

	  // The subject ID has been escaped so to counter SQL injection
      $safe_page_id = mysqli_real_escape_string($connection, $page_id);

	  // 2. Perform database query to find out which pages belong to the subjects we intend on displaying
	  $query = "SELECT * ";
	  $query .= "FROM pages ";
	  $query .= "WHERE id = {$safe_page_id} ";
	  $query .= "LIMIT 1";

	  $page_set = mysqli_query($connection, $query);

	  confirm_query($page_set);

      // Return an associative array containing the result set data from the execution of the above query
      if($page = mysqli_fetch_assoc($page_set)) {
	    return $page;
	  } else {
	  	return null;
	  }
	}

	function find_selected_page() {
	  global $current_subject;
	  global $current_page;
	  
      // At the start of the program read back the value related to the 
      // respective href but perfrom a check with regards to the 
      // setting of the variables which will hold the subject id and page 
      // id which will be used as part of the a href tag

      if(isset($_GET["subject"])) {
        $current_subject = find_subject_by_id($_GET["subject"]);
        $current_page = null;
      } elseif(isset($_GET["page"])) {
        $current_page = find_page_by_id($_GET["page"]);
        $current_subject = null;
      } else {
        $current_subject = null;
        $current_page = null;                
      }
    }
?>

To start with I intend on using the HTTPSocket to perform a simple read and display in a TextArea of my database content through reading what my php script returns. My attempt can be seen below. I’m I on the right path to displaying in XOJO say in a textarea the content of the div titled page in my 1st PHP script above i.e. manage_content.php?

  Dim desiredsocket As New HTTPSocket
  Dim desiredresponse As String
  Dim desiredquery As String
  
  desiredquery = "http://www.swim-mates.com/widget_corp/public/manage_content.php"
  
  desiredresponse = desiredsocket.Get( desiredquery,  10 )
  
  ResultArea.Text = DefineEncoding(desiredresponse, Encodings.UTF8)

Apologies for any basic errors i might have made in my above code.