How should be a dynamic website structured? - php

I have wrote my own CMS in PHP. It is quite simple, but it does not permit me to do some things, like the redirect with header() from dynamic page.
Here is its structure (very simplified):
<?php
$db = new PDO...
try {
//getting page info from database (by $_GET['id'])
//and put results into $pageInfo
$stmt->prepare
//.. catch etc...
?>
<!doctype html>
<html>
<head><title><?=$pageInfo['title'];?></title></head>
<body>
<?php
//this file below cannot contain a php redirect, because headers are already sent
include($pageInfo['content_path']);
?>
</body>
</html>
There is one page that is dynamic and can display other pages by changing the value of the get parameter id.
The included content often contains PHP scripts.
I have looked around the internet but I don't know how to resolve this issue.
May I create a header.html and a footer.html and include them into every page? But if I include the header file before including the content doesn't it send headers? How?
Really sorry if this question seems stupid, but I don't know how to do it. I haven't someone that teaches me, so I have to learn all by myself but for some things I don't know where to look.
Thanks in advance.

The preferred way is to have the application separated into several parts, one part that executes code (Controller or core) and another one that displays something (View or template).
For example in MVC (Model/View/Controller), your single page would be just a dispatcher that calls a controller, the controller executes PHP-code, and fetches some data by using the second part, the model, and finally calls a template to display the data.
In your example you could start by including two files for each call, one that contains only PHP-code and fetches all data, and after that one that contains a html-template with variables and only very simple code that is needed to display the data. You can then do redirects and exit in the php-part (controller).

Related

PHP: reload a php include function without reloading the page

I have a page that has a few php include functions, pulling in content from external php files to represent on the page. Like so:
<?php
include 'htmlblocks/catalog.php';
?>
What I am looking for is a way to reload one of those include functions when a button is clicked.
Is this possible and if so how would I go about doing this?
*The end goal is to have this specific file (the one that is included via php) take parameters from the url to use to select data in a SQL database *
Thanks in advance!

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):
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
User enters website with the system
User chooses parameters for filtering and sorting
User starts generating view
Data is being read from *.csv file
During above, data is being filtered and sorted
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
UC1
User chooses an option to share data
System displays question if user wants to send it to printer, or e-mail
User chooses option (for this case: e-mail)
System asks for e-mail address
User provides e-mail address
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 ^^'
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!):
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")
Then I've created a kind-of controller, that can use the model to pass data to a variable in my view.
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):
So here it is. An easy, not very long, not very short answer to my own question. Case closed :)

Keep all content to one section of a multi-row layout

I have a web application whose loading page presents a form with radioboxes for 3 types of input : Color, Size, Material. This loading page is basically a php file first.php that has 3 sections, a Header div, a Content div which presents the form and a footer div.
The action target for the Submit button is a 2nd file process.php which offers a page of choices. I want this file to exactly take up the space occupied by first.php - which is to say, I want the header and footer to stay as they are throughout the life of the
session. I could load the header and footer for every target php file but I'd rather save on the amount of content from server to browser.
What should I do to ensure that the 2nd(and every subsequent nth page) stays only in the content sub-section? The code for first.php is like this:
header comes here
<div id="content">
<form action="process.php" method="post">
.....
</form>
</div>
<div id="footer">
footer comes here
</div>
Thanks.
This is the method implemented by me: maybe not the best one, but the one giving me the best results without too many hassles.
make a framework page with all the HTML and some "holes" for the generated text, e.g. $header, $article, $footer and everything you have to change;
instead of a plain echo save the output into the variables above;
for every page include the framework as last line: include_once ('framework.inc'); and the "holes" will be filled.
BTW, I use also other variables for the CSS and Javascript specific to a certain page, for the <title> and other variable parts.
All the common php functions (session manipulation, DB management, etc.) are placed into another file, general.inc, included at the beginning of the page with include_once ('general.inc');.
If you want to hide those include files on your web server have their name starting with .ht, and Apache will not serve them.
I have read recently about dynamic loading content to just selected section by using JQuery Mobile lib: https://api.jquerymobile.com/pagecontainer/#method-load
Please check out engine descibed f.e. here: http://blog.stikki.me/2011/08/18/loading-dynamic-content-in-jquery-mobile-with-jquerys-load-function/
and of course remember about naming convention of jquery mobile sections.
IMHO it works quite good (;

My php/jquery/ajax design hierarchy isnt working

I currently have a site I built using jquery/php/PDO/mysql.
I use classes for most functions, including database, logins, content, etc...
I am wanting to change my forms over to jquery's ajax calls. But there's where my problems start. With the ajax call, I can't call a php function in the ajax post url. Heres the heirarchy Im using;
->content.php (form resides in a function named content.)
->process.php (post checks and then a call to add content from class)
->class.content.php (insert vars into db)
Once form is submitted, it goes to process.php which contains checks and then a class call to add content.
While this hierarchy seems to be the most used for ajax, it causes path issues. It breaks my db connection, my config connection, etc...
All I really want is to add ajax forms. But I don't want to rewrite my whole site. Any suggestions?
It sounds like process.php was previously included in content.php but now you're trying to submit to it directly. However, process.php was dependant upon the configuration variables, database connection etc. which was included in content.php and accessible by being included within that page.
I think you need to make a new page which includes the same other files and has the same initialisation code as content.php, except it doesn't output the form and instead just includes process.php, then submit to the new page.
Hard to say for sure without code though.

edit a file via php

I've look around, and not found anything yet. So I'm going to ask a question, sorry if this is 'nooby'
What I want to do is this:
Have a page with a form on it, IE: Form.php
and I want to allow myself to edit another page, IE: index.php
Kind of like a really BASIC two page CMS, edit it on the form.php page, and then it saves on index.php doesn't overwrite, but saves it under the current post that's already there.
Sorry for the 'vague' question, however want to do this fast :P
You can do it the way Patashu said with a database but if your only going to be editing one page you can do it with http://php.net/manual/en/function.fopen.php.
On the Form.php have it open index.php using PHP then have a textarea field that echos out the index.php and then using the Fopen function save over index.php. Make sure you secure Form.php with a password or even using a database. It also depends what programming language you will have inside index.php
Instead of editing HTML or PHP using a PHP file, you should make a database, store content in it that you want to be dynamic, and retrieve from the database when the PHP for the dynamic page executes. Go read about SQL :)
(reposting so it can be chosen as selected answer, if you want!)

Categories