Krzysztof Krzysztof - 2 months ago 6
PHP Question

How to properly communicate a parent PHP with embeeded PHP?

You may remember that not long ago I asked you for some help with objects transfering through $_SESSION in PHP (more: Data loss during sending via $_SESSION from one script to another ). Currently I'm reworking the whole project and I don't have a foggiest idea how to do it properly. I mean, how to do it "according to the art", not "at any cost / the easiest (but nasty) way".

Here's the mockup of what I want to achieve (animated gif):
enter image description here

As you can see, I want my website to display at startup only the navigation, in which I want user to set his starting parameters. In the future, the navigation bar will have ability to be collapsed (to extend the data display section's height). When user sets the parameters (or not - for default view) and clicks "FILTER AND SORT" (which probably will be renamed to "GENERATE"), the second section should appear with data filtered and sorted as user defined.

Data is read from CSV file and stored in PHP Objects defined by my custom classes I've shown you in the question linked above. So I need to communicate data between 5 files:

FRONTEND:

index.php
<-- my main file handling the website

FRONTEND-BACKEND:

navigation.php
<-- file that shall be displayed in the navigation div

data.php
<-- file that shall be displayed in the data section div / iframe (?)

popup.php
<-- file that appears in a div over the index.php when certain DataBox is clicked; handled with tinybox2.

BACKEND:

classes.php
<-- file with definitions of classes (properties and methods)


  • tinybox2 "library".



My communication flow is as to be:
navigation.php
displayed on the top of
index.php
sends filtering and sorting parameters to
data.php
, making it appear on the bottom of
index.php
.

data.php
and
popup.php
shall use classes contained in
classes.php
constructed from CSV file
datafile.csv
.

When a DataBox is clicked in
data.php
,
popup.php
appears over
index.php
content to display extended object data.

So, how should I do this, to make it properly? Which option will be best: $_POST, $_SESSION or maybe something else? Maybe due to embeeding all files in / over
index.php
it is possible to store all data in such a way, that no communication is needed? How to embeed files - with include, require or maybe other way?

There are lots of assisting questions, but still, the most important is: how to do it properly? Thank you for your help in advance :)

PS For certainty, please find below one additional usecases:

UC1: Standard use of display system


  1. User enters website with the system

  2. User chooses parameters for filtering and sorting

  3. User starts generating view

  4. Data is being read from *.csv file

  5. During above, data is being filtered and sorted

  6. Data is being displayed by the system to the user



Extensions:

5a. No data to display: system displays empty data section

6a. User want's to filter and sort again: back to step 2.

UC2 (OPTIONAL): User wants to share the data


  1. UC1

  2. User chooses an option to share data

  3. System displays question if user wants to send it to printer, or e-mail

  4. User chooses option (for this case: e-mail)

  5. System asks for e-mail address

  6. User provides e-mail address

  7. System sends an e-mail with the current
    data.php
    data as it is displayed on website.



PPS I know I should show you some code snippets, but my current code is a mess with lots of interchanging html, php and comments, that cannot be cut of from the system (or would take me ages to clean it up to show it here). I'm asking you for help mostly, because I really want to remodel the current solution, therefore I'm rewriting the code from zero, using old one as a hint, not a template. Like Microsoft did with Windows Vista and Windows 7 :P Hope you'd understand ^^'

Answer

Okay, so here it is. The ultimate answer to a question some understands as too wide.

What was the case:

I wanted to achieve a two-section page, where the first (partent) section takes user input and uses it to filter the data in the second section. The problem was with providing parameters from the parent side to the invoked one.

What I had to change in my conception:

At first I thought about passing data with $_SESSION or other PHP way, BUT there is one major problem with such way of thinking:

As PHP is server side interpreted, it cannot dynamically add another page without refresh!

I know I didn't intent a new lightbulb or explore America, but it's still this conclusion what leaded me to accept the fact, that JavaScript usage is inevitable. I think most beginners will find this important: you need to completely change your way of thinking, as website ain't the same thing as traditional application. After this, it finally came to me (thanks to @Yoshi) that my initial problems with jQuery weren't a good reason to hold back from using it and I had to find out what they were.

Solution comes here:

Okay, so what is the solution?

I've started up with finding out what was wrong with my jQuery and... it was wrong way of interpreting "what is the scope of code included into php". If I include view/header.htm file into index.php that lays in the root directory, it will behave as it was in the root directory, not view directory. And that was the stupidest, as well as not uncommon error that one can make.

After finding this out (thank you @Yoshi again!):

  1. I've created backend (model) for my app that can:
    • Read data from file
    • Put data into a class-based storage (that will in the future be then exported into a php file as "pseudo-database")
  2. Then I've created a kind-of controller, that can use the model to pass data to a variable in my view.
  3. At least I've created a view for my site, with the "parent site" (it has a backend part with a main-controller, and a frontend part with a view), and a "invoked site" that is opened through jQuery request, and contains a filtering backend and the main data view.

These 3 not-so-easy at first, but now so-so-essential, steps took me here. Please find some php-pseudocode below:

model_Data.php

<?php
    // Class for single instance of data storage

model_DataSet.php

<?php
    // Class for set of data instances storage

model_ReadData.php

<?php
    // Code for reading CSV file with fgetcsv function

controller_DataMaster.php

<?php
    require_once 'model_Data.php';
    require_once 'model_DataSet.php';
    require_once 'model_ReadData.php';
    // Read data from file to a variable
    $reader = new ReadData();
    $reader->setConfiguration(//some setup);
    $tmp_data = $reader->read("filename");
    // Put data into the class
    $dataSet = DataSet($tmp_data);
    return $dataSet;

index.php (which is the main controller!)

<?php
    header('Content-Type: text/html; charset="UTF-8"');

    include 'view/header.htm';

header.htm contains HTML headers, includes of jQuery and jQuery-UI (for sake of datepicker) as well as css references, and (of course) physical header of the website with the input form displayed.

view.php

<?php
    $import = include 'controller_DataMaster.php';

    $usableData = $import->getAllDataSingles();

    if (isset($_POST['data_from_the_form']))
    {
        // Do something!!!
    }
?>

<table>
    <tr>
        <?php $i = 1; foreach($usableData as $singleData): ?>
            <td><pre><?php print_r($singleData->getAllProperties()); ?></pre></td>
            <?php if ($i++ % 3 == 0): ?>
                </tr><tr>
            <?php endif; ?>
        <?php endforeach; ?>
    </tr>
</table>

And this way you can achieve something that looks like this (currently - without any CSS applied):

enter image description here

So here it is. An easy, not very long, not very short answer to my own question. Case closed :)

Comments