This is my first attempt to write a very simple (one-file) blog-engine, build with PHP and MySQL. I want to make and have everything simple and don't want to include hundreds of files, classes and so on, because I just want to publish some text and that's is. I don't need plugins, changing templates, APIs or anything like that. The script is now working and running fine, but I'm a really novice and have just started with php/mysql. :)
So I want some feedback, what I've done wrong, what is maybe too complicated or if there is a possibility of injections or similiar? Any help and feedback is welcome (and sorry for my poor english!).
I've include some comments, so that's easier to follow my thoughts:
<?php
///////////////////////////////////////////////////// BASE
// Whats the name of the blog and how many recent articles should shown on the front
$blogname = 'The basic blogname';
$anzahl = '3';
// Alright, let's connect to the database
include_once 'include/connect.php';
// I use this to generate german date (e.g.: March --> März)
setlocale (LC_ALL, 'de_DE#euro.utf8', 'de_DE.utf8', 'de.utf8', 'ge.utf8');
///////////////////////////////////////////////////// START >>> IF
// As we using htaccess with modrewrite, we want to know, what page-name the user requested
if (isset($_GET['slug'])) {
// I'm not sure, if it makes sense (mysqli_/mysql_?) to avoid injections? Any help is welcome!
$blog = mysql_escape_string($_GET['slug']);
// Alright, now we check the database and ask if the sitename exist and if the status is "online" (published/draft)
$result = mysqli_query($con,"SELECT * FROM entries WHERE slug='$blog' AND status = 'ONLINE'");
// We call the result and check, if there is a article in the database
$num_results = mysqli_num_rows($result);
if ($num_results > 0){
// We now also include the header-file, because there we also have the $title-variable for the site / browsertab
include 'header.php';
include_once 'markdown.php';
// Create variables from the database-fields, also convert the content with markdown
while($row = mysqli_fetch_array($result)){
$title = $row['title'];
$content = $row['content'];
$my_html = Markdown($content);
$date = $row['date'];
$date = strftime('%d. %B %G', strtotime($date));
// and final: show the article on the website
echo '<h2>' . $title . '</h2>';
echo '<div id="date">' . $date . '</div>';
echo '<div id="content">' . $my_html . '</div>';
echo '<div id="link">Back to front-page</div>';
// we also inlucde the footer, so that we have a complete page - header/content/footer
include 'footer.php';
}
///////////////////////////////////////////////////// ELSE >>>
// but if there is NO entry in the database with this pagename...
} else {
// again we need the header
include 'header.php';
// then we say:
echo '<h2>Error</h2>';
echo '<div id="content">There is no article with this name!</div>';
echo '<div id="link">Back to front</div>';
// and include the footer
include 'footer.php';
}
///////////////////////////////////////////////////// ELSE >>>
// But if the user just open the blog and don't request a name, we want to show him the last articles (3 - see top)...
} else {
// So again we call the database and request the last published entries and sort them, limited by the amount of given entries
$result = mysqli_query($con,"SELECT * FROM entries WHERE status = 'ONLINE' ORDER BY id DESC LIMIT $anzahl");
// Again include header and markdown
include 'header.php';
include_once "markdown.php";
// We generate variables from the datebase during the loop, also convert the excerpt with markdown
while($row = mysqli_fetch_array($result)){
$title = $row['title'];
$slug = $row['slug'];
$excerpt = $row['excerpt'];
$my_html = Markdown($excerpt);
$date = $row['date'];
$date = strftime('%d. %B %G', strtotime($date));
// And publish them on the website
echo '<h2>' . $title . '</h2>';
echo '<div id="date">' . $date . '</div>';
echo '<div id="content">' . $my_html . '</div>';
echo '<div id="link">Read more...</div>';
}
// Last time, we include the footer again.
include 'footer.php';
}
///////////////////////////////////////////////////// <<< FINISH
?>
Thanks - and yes, I'm willing to learn! :))
By using SQL abstraction library and templates you can make your code more tidy
$sql = "SELECT * FROM entries WHERE slug=?s AND status = 'ONLINE'";
$row = $db->getRow($sql, $_GET['slug']);
if ($row) {
$title = $row['title'];
$content = Markdown($row['content']);
$date = strftime('%d. %B %G', strtotime($row['date']));
$tpl = 'single.tpl.php';
include 'main.tpl.php'
} else {
include '404.php';
}
and for the list
$sql = "SELECT * FROM entries WHERE status = 'ONLINE' ORDER BY id DESC LIMIT ?i";
$data = $db->getAll($sql, $anzahl);
$tpl = 'list.tpl.php';
include 'main.tpl.php'
Related
i would like to retrieve single current page instant off full menu with currents
menu code :
<?php
$sql = mysql_query("SELECT * FROM pages WHERE isRoot='1' ORDER BY pageID");
while ($row = mysql_fetch_object($sql))
{
echo "<li class=\"current\">$row->pageTitle</li>";
}
?>
preview code :
?php
//if no page clicked on load home page default to it of 1
if(!isset($_GET['p'])){
$q = mysql_query("SELECT * FROM pages WHERE pageID='1'");
} else { //load requested page based on the id
$id = $_GET['p']; //get the requested id
$id = mysql_real_escape_string($id); //make it safe for database use
$q = mysql_query("SELECT * FROM pages WHERE pageID='$id'");
}
//get page data from database and create an object
$r = mysql_fetch_object($q);
//print the pages content
echo "<h1>$r->pageTitle</h2>";
echo $r->pageCont;
?>
but it gives me li pages marked with current
I think I understood what you meant... I would try something like this:
<?php
$sql = mysql_query("SELECT * FROM pages WHERE isRoot='1' ORDER BY pageID");
while ($row = mysql_fetch_object($sql))
{
$active = '';
if($_SERVER['REQUEST_URI'] == DIR . '?p=' . $row->pageID)
$active = 'class="current"';
echo "<li " . $active . ">$row->pageTitle</li>";
}
?>
This way, you will only add the 'class="current"' if the user is actually on this page.
Hope this helps!
Hi guys I am relatively new to php and am wondering how there is a cleaner way to retrieve data from my database and show it across different parts of the webpage?
For example see my current code...
<?php
$result = mysqli_query($mysqli,"SELECT * FROM members WHERE email='".$_SESSION['email']."'");
while($row = mysqli_fetch_array($result)){
if($_SESSION['email'] == $row['email']) {
// If you find the right user with the same E-Mail address, DO SOME COOL THINGS :)
}
echo '<h2>'. $row['username'] . '</h2>' ;
echo 'Hi, I am a ' . $row['yourage'] . ' year old ' . $row['orientation'] . ' ' . $row['gender'] . ' looking for a ' . $row['lookingfor'] . '.<br /><br />';
echo 'I am currently living in the ' . $row['location'] . ' area.';
echo '<button>Get in touch</button>' . '<br>';
echo '<br /><br />';
echo '<hr />';
echo '<h2>About me:</h2>';
echo $row['aboutme'] . '<br>';
}
mysqli_close($mysqli);
?>
If I copy this again on the page it kills the script but wondering what the best practice is?
First of all, a much better approach to this would be to separate your database and view code, for example by using an MVC framework (such as CakePHP).
But here is what I would do if was doing this a similar way to you: (You are only selecting one result from the database, if you were selecting many, this would be different.)
At top of page:
<?php
$email = $_SESSION['email'];
$result = mysqli_query($mysqli,"SELECT * FROM members WHERE email='".$email."'");
while($row = mysqli_fetch_array($result)){
$member = $row;
}
mysqli_close($mysqli);
?>
then whenever you need to display the data in the page: (for example)
My username is <?php echo $member['username']; ?>
Maybe you should separate the query script (below) from the viewing part.
query.php
<?php
$result = mysqli_query($mysqli,"SELECT * FROM members WHERE email='".$_SESSION['email']."'");
while($row = mysqli_fetch_array($result)){
if($_SESSION['email'] == $row['email']) {
// If you find the right user with the same E-Mail address, DO SOME COOL THINGS :)
}
$returnArray[] = $row['username'];
$returnArray[] = $row['yourage'];
//and so on;
}
mysqli_close($mysqli);
?>
Some view.php (or index.html renamed to index.php):
<?php
include('query.php');
var_dump($returnArray);
//Or with a foreach or however
But you should learn about MVC Model View Controller and as others said, use OO programming
Learn ajax- this will help you separate this code from your application. Just make the ajax call to this php and get the result and show them how you want to show.
For example-
In a your application, say app.html, at the point you want to fetch something from db-
$.ajax({
type: "GET",
url: "fetch.php", // your aove php file
function(response){
console.log(response); // you'll get all the rows here
response=JSON.parse(response);
for(var i=0; i<response.length; i++){
console.log(response[i].username); // show results in view
....
}
}
});
fetch.php
$myrows = array();
while($row = mysqli_fetch_array($result)){
array_push($myrows, $row);
}
echo json_encode($myrows);
The reality is you want a templating engine of some sort to filter your database results directly into the template.
So rather than dealing with echo commands to design a page, you want a raw template and then to inject data into that template from your database array.
You can use something standardized like Mustache or roll your own fairly easily (although rudimentary):
$output = '';
$tpl = fopen('template.html','r');
$tpl = fread($tpl, 100000);
$templateVars = array();
while($row = mysqli_fetch_array($result)){
$temporaryRow = $tpl;
foreach ($row as $k=>$v) {
$temporaryRow = preg_replace("/{{$k}}/i",$v,$temporaryRow);
}
$output .= $temporaryRow;
}
echo $output;
And then your template.html could be something like
<div>Hello, {{username}}</div>
Hey guys hope someone can help with this.
I am using substr to give an abstract of articles. Now the problem is when you click the link to see the whole article you still see the substr version. Now this obviously happens because of the way the code is.
I need to make another query that will say if someone clicks the link then display the full article without the substr. I have no idea how to go about this can anyone help? While I am learning my PHP knowledge is fairly limited.
<?php
class MyCMS
{
function get_content($id = "")
{
if ($id != ""):
$id = mysql_real_escape_string($id);
$sql = "SELECT * FROM content WHERE blog_id = '$id'";
$return = '<p> Go Back To Content Page</p>';
else:
$sql = "SELECT blog_id, title, date, body FROM content ORDER BY blog_id DESC LIMIT 0, 3";
endif;
$res = mysql_query($sql) or die(mysql_error());
if(mysql_num_rows($res) !=0):
while($row = mysql_fetch_assoc($res))
{
echo '<div id="roundedbox"><h2>' . $row['title'] . ' </h2>';
echo '<div id="date"><h5><p>' . $row['date'] . '</p></h5></div>';
echo substr('<p>' . $row['body'] . '</p>',0, 90)." .... "." read more </div>";
}
else:
echo '<p> UH OOH! THERE IS NO SUCH PAGE IT DOES\'T EXIST </p>';
echo $return;
endif;
}
}
?>
Normally you would encapsulate the article into a data class (alias "Model", see MVC architecture). This model holds all the data of the article and have a method to return the abstract or the long version of the article. To identify the version the client would like to see, pass another argument to your URL.
class Article {
protected $text;
protected $title;
public __construct ($title, $text) {
$this->title = $title;
$this->text = $text;
}
/**
* Returns the short excerpt of the article
*/
public getShortAbstract () {
// your substr() function
}
/**
* Returns the full article
*/
public getText () {
return $this->text;
}
}
Add another argument to the function to determine whether it returns the full article or an excerpt:
<?php
class MyCMS
{
function get_content($id = "", $excerpt = FALSE)
{
if ($id != ""):
$id = mysql_real_escape_string($id);
$sql = "SELECT * FROM content WHERE blog_id = '$id'";
$return = '<p> Go Back To Content Page</p>';
else:
$sql = "SELECT blog_id, title, date, body FROM content ORDER BY blog_id DESC LIMIT 0, 3";
endif;
$res = mysql_query($sql) or die(mysql_error());
if(mysql_num_rows($res) !=0):
while($row = mysql_fetch_assoc($res))
{
echo '<div id="roundedbox"><h2>' . $row['title'] . ' </h2>';
echo '<div id="date"><h5><p>' . $row['date'] . '</p></h5></div>';
if ($excerpt):
echo substr('<p>' . $row['body'] . '</p>',0, 90)." .... "." read more </div>";
else:
echo '<p>' . $row['body'] . '</p>';
}
else:
echo '<p> UH OOH! THERE IS NO SUCH PAGE IT DOES\'T EXIST </p>';
echo $return;
endif;
}
}
?>
Then when you are calling the get_content() function, pass it the id and excerpt flag as follows:
get_content(123, TRUE); //for excerpt
get_content(123); //for full post
I don't think you want to do this with PHP, because when you're doing this with PHP you have to refresh the whole page.
I would advise you to use Javascript for this, like the jQuery library slideToggle.
With this method, Google will still index all the content.
I am having this website http://www.finalyearondesk.com . My blogs post link are set like this.. http://www.finalyearondesk.com/index.php?id=28 . I want it to set like this ... finalyearondesk.com/2011/09/22/how-to-recover-ubuntu-after-it-is-crashed/ .
I am using the following function to get these posts...
function get_content($id = '') {
if($id != ""):
$id = mysql_real_escape_string($id);
$sql = "SELECT * from cms_content WHERE id = '$id'";
$return = '<p>Go back to Home page</p>';
echo $return;
else:
$sql = "select * from cms_content ORDER BY id DESC";
endif;
$res = mysql_query($sql) or die(mysql_error());
if(mysql_num_rows($res) != 0):
while($row = mysql_fetch_assoc($res)) {
echo '<h1>' . $row['title'] . '</h1>';
echo '<p>' . "By: " . '<font color="orange">' . $row['author'] . '</font>' . ", Posted on: " . $row['date'] . '<p>';
echo '<p>' . $row['body'] . '</p><br />';
}
else:
echo '<p>We are really very sorry, this page does not exist!</p>';
endif;
}
And I am using this code to dispaly it on my index.php page...
<?php
if (isset($_GET['id'])) :
$obj -> get_content($_GET['id']);
else :
$obj -> get_content_summary();
endif;
?>
Any suggestions how to do this? And can we do this by using .htaccess?
The unfortunate thing about using mod_rewrite is that the data you are supplying in the form of a url is not the best way to query a database. But none the less you have year, month, day and title variables so you will need to rewrite your get_content function to query soomething like (depending on how you date is stored in the database.):
select * from cms_content
WHERE date='mktime(0,0,0,$month,$day,$year)'
AND title='$title'
ORDER BY id DESC
.htaccess would be something like:
RewriteRule ^(.*)/(.*)/(.*)/(.*)$ index.php?year=$1&month=$2&day=$3&title=$4
I am setting up a webpage for a student organization with bios for the officers along with pictures and whatnot.
the first page simply is html and css. it has a picture, name under it and a link to the full bio where it links to "bio.php?id=" and then the id in my SQL database for that person.
now i am trying to make the php page to allow a simple template php page using the user's id. unfortunately when i do everything that I think is right, I get an odd error.
here is my code
<html>
<body>
<?php
//connection to database
//specify database
$id= $GET['id'];
$sql = " SELECT * FROM Members_table WHERE Id='$id' ";
$result = mysql_query($sql) or print ("Can't select entry from table bloghomepage.<br />" . $sql . "<br />" . mysql_error());
WHILE($row = mysql_fetch_array($result)) {
$name = $row['Name'];
$position = $row['Position'];
$major = $row['Major'];
$hometown = $row['Hometown'];
$awards = $row['Awards'];
$bio = $row['Description'];
$act = $row['Activities'];
$pic = $row['Picture'];
$misc = $row['other'];
?>
<h1><?php print $name; ?></h1>
<p><?php print '<img src="' . $pic . '"'; ?>
<?php } ?>
</body>
</html>
This is what i see on my webpage:
" . $sql . "
" . mysql_error()); WHILE($row = mysql_fetch_array($result)) { $name = $row['Name']; $page_id= $id; $position = $row['Position']; $major = $row['Major']; $hometown = $row['Hometown']; $awards = $row['Awards']; $bio = $row['Description']; $act = $row['Activities']; $pic = $row['Picture']; $misc = $row['other']; ?>
and thats all. any ideas what i am doing wrong?
you just don't have PHP enabled on your host.
Hint: always see page source, not picture rendered by browser. It's HTML code being result of your PHP script, so, you have to check HTML code, not a picture rendered from it.
The PHP isn't being parsed, presumably because the necessary module/content handler isn't set up within your web server.
It's not directly related to the topic but you might want to cast the value of the GET parameter as an integer before reusing it in a query to prevent basic SQL injection
$id = intval( $_GET['id'] );