I posted in a previous question how to get my rating script to work. I have now finally got it to work using maths rather than the avg function but i still have two questions to ask.
Q1) Is there a better way of displaying my results other than using echo all the time
Q2) How do i add in my other three performance values in to this script they are all in the same table
<?php
mysql_connect("localhost", "username", "password") or die ("sorry we could not connect to our servers");
mysql_select_db("db") or die ("sorry we could not our database");
$find_data = mysql_query("SELECT * FROM rating");
while($row = mysql_fetch_assoc($find_data))
{
$id = $row['id'];
$current_rating = $row['Reliability_timekeeping'];
$reviews = $row['reviews'];
$new_rating = $current_rating / $reviews;
echo "($reviews Reviews)";
echo "Reliability & timekeeping: ";
echo round($new_rating,1);
echo "/10";
}
?>
sorry for my writing skill writing is not my strong point and still new to php
You can use a template engine that fills your data in to a template that you can write like HTML with some additional placeholders. A template engine has some great advantages over echoing out the values:
separate code from layout
reusable
better maintainability and readability
Here are some of the template engines I used in PHP, they also have good documentation to get you started:
Smarty
Twig
To avoid using echo all the time, you can just accumulate all the output in a variable and use a single echo. As a good practice, in my scripts I try to use just one echo at the script end. This will make each page a few mili-seconds faster, as less PHP / web server interactions will be necessary:
$Response = "";
$Response .= "($reviews Reviews)".
"Reliability & timekeeping: ".round($new_rating,1)."/10";
...
more code
...
echo $Response;
Just indent and break lines in a way that the code gets readable, and everything will be fine.
Related
I am atm making a website where I'm storing all of my HTML based pages in a mysqli database, and I came to this problem where I couldn't execute my PHP code by using echo. So I found this solution where I had to use eval(); in order for my PHP code to run, I heard it could be really dangerous if you do not validate it correctly.
$firstname = htmlspecialchars($mysqli->real_escape_string($row['firstname']));
So far this is how I have been validating it, would this be secure enough?
Note: that line of code is used when I request the information from the database, to be display on the page.
I'm sorry if I haven't explained myself well enough, I'm still new to this. :)
This is how i get my pages from the database.
<?php
if (isset($_GET["page"]) && $_GET["page"] != null) {
$query = "SELECT * FROM pages WHERE pagename = '$_GET[page]'";
$result = $mysqli->query($query);
while ($row = $result->fetch_array(MYSQLI_ASSOC)){
$pagetitle = $row["pagetitle"];
$pagename = $row["pagename"];
$pagecontent = $row["pagecontent"];
}
} else {
$query = "SELECT * FROM pages WHERE pagename = 'index.php'";
$result = $mysqli->query($query);
while ($row = $result->fetch_array(MYSQLI_ASSOC)){
$pagetitle = $row["pagetitle"];
$pagename = $row["pagename"];
$pagecontent = $row["pagecontent"];
}
}
?>
real_escape_string simply removes any characters that might be used for SQL injection. If you execute user input as PHP code you give your users the same possibilities you have in your php scripts. Including running system commands to remove all files from your server for example.
You don't want to be doing this. That particular case you are mentioning, can you elaborate on that? There is probably a better solution to your problem.
I'd just like to say that you're doing two things here that are generally considered bad practices.
Storing code that will be executed in a database. (Always store code in text files, that way they're version controlled and also less vulnerable to sql attacks).
Using eval().
Both are these are bad ideas and will almost certainly bite you in the ass at some point.
What is it that you're trying to do?
I am working in a project which has the following restriction defined:
My PHP files must not have more than one opening or closing tag.
So it's PHP from top to bottom, but I am allowed to add static content by the means of 'import'.
What are proper/elegant ways to add static HTML content to my PHP index file (like outputting a website menu header or a formular) and at the same time resolve PHP variables inside the file.
Like a formular which makes a HTTP POST (login or register) and displays the previously entered email address in case of a mismatch, etc etc.
One way would be
echo "<form ...> \n <input ... value='$lastemail'>";
But I dislike the quoting. echo <<< EOF is also not great for the purpose imho.
I think HTML code should stay together without separating it into multiple echos so it can be validated.
So I am looking for a good solution to import/integrate static HTML code, like a template system and still resolve PHP variables.
Update:
The restriction is made to not mix HTML and PHP code.
I think I will need an engine/class/function which replaces variables inside a HTML template with PHP code. Like searching for ${variable} and replacing it with the php $variable as if it was PHP code.
I just thought maybe there is already something existing within PHP to solve that.
Update:
Should I oppose the requirement ?
Would be very interesting to hear the oppinion of a professional PHP developer with long history in that area. (On The restriction is made to not mix HTML and PHP code. )
Perhaps you could use a templating system? There are plenty out there for PHP. Some nice ones are (in my opinion):
Twig, which is very small and fast
Smarty, a little larger, but also fast and very popular
The solution that I provide now may seem lengthy and strenuous to enact but would one of the best ways to solve problems with such constraints. Create a database with two tables, one of which would store all the static data i.e. HTML code whereas the other would store dynamic data i.e. data that you want to be personalised. You can then use the database to separately eject dynamic and static data, all using just pure PHP.
<?php
$host = "127.0.0.1";
$user = "root";
$password = "****";
$db = "project";
$txt = NULL;
$conn = mysqli_connect($host, $user, $password, $db);
if(!conn){
header("location:error.htm");
}
$query1 = "SELECT dynamicdata FROM projectdynamicdata WHERE pagename ='index'";
$resultset1 = mysqli_query($conn, $query1);
while($row = mysqli_fetch_assoc($resultset1){
$txt = $row["dynamicdata"];
}
$query2 = "SELECT htmlpage FROM projectstaticdata WHERE pagename='index'";
$resultset2 = mysqli_query($conn, $query);
while($row = mysqli_fetch_assoc($resultset){
echo $row["htmlpage"];
}
mysqli_close($conn);
?>
This is what I would to solve such a problem.
Alright so I have no idea how to even begin doing this
But basically I have one of the menus that displays on every page come getting it's text and links from a mysql database.
Here's the code:
<table class="LeftMenuTable">
<?php
// Generates the left menu from the LeftMenu_items table
$result = MySqlQuery("SELECT * FROM Menu_LeftMenu;");
while ($row = mysqli_fetch_assoc($result))
{
if ((int)$row['header'] == 0)
{
// echos value is on or not
echo "<tr><td class='LeftMenu'><a href='" . $row['url'] . "'>" . $row['text'] . "</a></td></tr>";
}
else if ((int)$row['header'] == 1)
{
// header
echo "<tr><td style='border:0px; height:5px;'></td></tr>"; // adds extra empty tabel
echo "<tr><td class='LeftMenuHeader'><b><strong>" . $row['text'] . "</strong></b></td></tr>";
}
}
?>
</table>
function MySqlQuery($Query)
{
$result = $mysqli->query($Query) or die(ReportMysqlError(mysqli_error($mysqli), $Query));
return $result;
}
I feel like any sql queries that could be be replaced by html cache somehow are reducing the site's speed.
If anyone has any information or suggestions it's much appereciated.
If you were keen enough, I would suggest a slightly different approach.
If you make your pages using a templating language called "Smarty" find out more here. http://smarty.net you should find that smarty will manage the caching for you.
How is this related to your question.
It will make your web development easier as you will stop "echoing" content into your HTML.
Smarty will do the caching for you. When a smarty template loads, smarty keeps a copy of it (or you can tell it cache a file for x hours, days etc).
As you site grows smartys caching will help keep your site running and loading fast.
You have to very little work to make caching work, just use smarty templates to build your site.
Lastly you may find it a LOT simpler to build sites using smarty.
John.
In the method that calls your database (to fetch menu items and build the corresponding html):
Check if there is an item in the current $_SESSION with the html of your menu.
If (1) returns nothing, execute the query, build the html and store the results in $_SESSION.
Return the html of your menu.
A bit more information about how you can use the session can be found here.
This way, your menu query will only be fired once per session. I doubt it's a real performance breaker though (if your query is more or less in normal form).
Note that changes in your menu will not get picked up automatically before the session expires with the mechanism described above.
I usually use memcached (or some other similar solution) when I need to organize a caching layer.
But in your case may be it'd be done in a more simple way: use an intermediate 'generator' script which will be fired each time the table in question is updated (as it's updated from some form of admin panel, right?) and will generate a static file, then include this file within your main view script.
I put together a simple script that pulls the product name, category name and product id from two tables. Then I take that data and use it to create a page title that's better than what I currently have for SEO purposes. For some reason I didn't think it would take as long as it's taking to run. There are 7k products.
My hosting company does allow the creation of a custom php.ini so I was able to override the 30 second time limit and changed it to 6000. But still the script times out. So I thought my script my suck. :)
Below is the script. Is there a better way I could write this so it doesn't time out? Or is what I'm trying to do just going to take some time and I need to write the script to do one category at a time?
<?php
// Make a MySQL Connection
mysql_connect("localhost", "myusername", "mypassword") or die(mysql_error());
mysql_select_db("mydatabase") or die(mysql_error());
$result = mysql_query("SELECT isc_products.prodcode, isc_products.prodname, isc_categories.catname FROM isc_products, isc_categories WHERE isc_products.prodcatids = isc_categories.categoryid")
or die(mysql_error());
while($row = mysql_fetch_array($result)){
$pname = mysql_real_escape_string($row['prodname']);
$catname = mysql_real_escape_string($row['catname']);
$sitename = Sitename;
$prodcode = $row['prodcode'];
$result2 = mysql_query("UPDATE isc_products SET prodpagetitle = '$pname - $catname - $sitename' WHERE prodcode = '$prodcode'")
or die(mysql_error());
}
?>
indexes http://www.threewestcreative.com/indexes.jpg
Thanks, your help is appreciated. :)
Thanks SO much everyone! I really appreciate the quick responses. I can't believe I overlooked something so simple as running a direct query against the database (without php). Geez... Thanks again!
Just run
UPDATE isc_products
INNER JOIN isc_categories ON isc_products.prodcatids = isc_categories.categoryid
SET isc_products.prodpagetitle=CONCAT(isc_products.prodname,' - ',isc_categories.catname,' - $sitename');
If it times out, your DB is fishy (missing indices?)
You can just use one query to do what you want.
UPDATE ssc_products, isc_categories
SET psc_products.prodpagetitle = CONCAT_WS(' - ', isc_products.prodname, isc_categories.catname, $sitename)
WHERE isc_products.prodcatids = isc_categories.categoryid;
Can you show your tables(s) structure? Its important when dealing with that many products, indexing is key. Also (while) loop is bad here, it will effect performance. Like the guys mention above 1 query should do the trick.
I'm not sure why you're doing this in PHP, given that you could achieve this with a single UPDATE. Perhaps you've left out bits that do things like identify which records have already been changed?
So I'll assume you really do want to do this in PHP, and that you just want to run this script once in order to update the prodpagetitle field table-wide.
One option would be to split this into separate scripts. Have a main script that does the SELECT, then skips through the UPDATEs by calling a second script, with the data to use in variables in the GET. For example:
<?php
// Make a MySQL Connection
mysql_connect("localhost", "myusername", "mypassword") or die(mysql_error());
mysql_select_db("mydatabase") or die(mysql_error());
$result = mysql_query("SELECT isc_products.prodcode, isc_products.prodname, isc_categories.catname FROM isc_products, isc_categories WHERE isc_products.prodcatids = isc_categories.categoryid")
or die(mysql_error());
while ($row = mysql_fetch_array($result)) {
$pname = mysql_real_escape_string($row['prodname']);
$catname = mysql_real_escape_string($row['catname']);
$sitename = Sitename;
$title=sprintf("%s - %s - %s", $pname, $catname, $sitename);
$url=sprintf("http://example.com/update.php?pcode=%s&title=%s", $row['prodcode'], $title);
$junk=file_get_contents($url)
}
?>
and:
<?php
// This is update.php, called by the script above.
mysql_connect("localhost", "myusername", "mypassword") or die(mysql_error());
mysql_select_db("mydatabase") or die(mysql_error());
$qfmt="UPDATE isc_products SET prodpagetitle = '%s' WHERE prodcode='%s'";
mysql_query(sprintf($qfmt, $_GET['pcode'], urldecode($_GET['title']));
?>
Node that this should be considered EXAMPLE code. I haven't tested it and don't plan to. You probably want to include some facility to mark your already-changed fields, so that you can continue on from whence you left off if the new script also times out (which it probably will). This script contains vulnerabilities, and should only be run in a secure environment or with significant modification to make it safe. </fineprint>
I'm working on revamping my CMS right now. Currently, I'm trying to minimize the front end code to make theming easier. To display the latest posts, this is the code I am using:
<?php
$query = mysql_query("SELECT * FROM posts order by id desc") or die(mysql_error());
while($row = mysql_fetch_array($query)) :
?>
<h3><?php echo $row['title'] ?></h3>
<?php endwhile; ?>
What would be the best way to simplify this for the front end user? I'm thinking about using a functions.php file but I not sure exactly how to do that. Is there a way I could make the first two lines of php into a function and then the user would only have to call the function?
Typically you use two layers.
Database access layer: Query function accepts arbitrary queries, verifies return value, logs to file on error, dies if needed. You can create separate functions for querying+retrieving data in one step (query_one_row(), query_dataset_as_array(), ...).
Data model layer: Separate functions for each major query, each calling the lower layer. eg: get_recent_posts(),
Try to rewrite #Sascha's answer to use these two layers.
Here is the function you could use:
function getPosts() {
$query = mysql_query("SELECT * FROM posts order by id desc") or die(mysql_error());
$result = array();
while($row = mysql_fetch_object($query)) {
$result[] = $row;
}
return $result;
}
and in the template:
<?php foreach(getPosts() as $post) : ?>
<h3><?php echo $row->title ?></h3>
<?php endforeach; ?>
note: i know I'm not answering your question, but just wanted to give you a heads up.
you might want to split the different concerns of the code. on one hand there is the render of the data, on the other hand, the business logic and the persistance layer. it seems you're coding everything in one file and this may make matters complex in the future. try using an mvc like yii, zend framework, or symfony2.
also, the "or die" is pretty much a bad practice. notice how you are loosing the chance of logging the error properly and outputing the error directly to the user instead of giving them a nice error page to look at, and maybe give you some feedback about the error.
edit: for the persistance layer, you could try doctrine2
To improve a little on Sascha's answer above, you could do this...
<?php
foreach(getPosts() as $post)
{
printf( '<h3>%s</h3>', $post->id, $row->title );
}
?>
Works exactly the same, but a bit easier to read, imo.