search
HomeBackend DevelopmentPHP TutorialPHP imitation blog park personal blog database and interface design_PHP tutorial

PHP imitation blog park personal blog database and interface design_PHP tutorial

Jul 20, 2016 am 11:16 AM
phpandpersonalbutblogBlog GardenlandMore than half a yeardatabaseoff and oninterface designSelf-studystill

I have been learning PHP by myself for more than half a year, intermittently, but in the end I firmed up my mind and continued PHP, so I wrote this PHP blog to find a stable PHP job without asking for a high salary. , but looking for a place to take shelter. I can understand most English documents. I am not stupid and I love learning. If you are interested, please contact me! Come if you are sincere! qq:240382473
I will release all key codes and documentation instructions in 3-5 times, and all styles in the blog backend will be applied to the blog garden!

Description:

1. It does not completely adopt the MVC architecture, but the concept is like this. Because it is not possible to write a very stable MVC architecture.
2. JQUERY AJAX is almost never used because I am not very familiar with it and can’t use it freely. You can use AJAX for guestbooks, no problem.
3. There are several public classes, and other codes are all handwritten. Please point out any shortcomings. Thank you very much.
4. Criticism and guidance are welcome, but please give your reasons.

Closer to home: Let’s look at the database architecture first

The engines of these tables are all MYISAM, which is convenient for access. (The yellow key represents the primary key; the blue diamond represents a non-empty field; the white diamond represents a null field) The links in the picture only represent a potential relationship between them and cannot be associated during operation. Because the search engine is MyISAM . Therefore, joint queries and multi-table operations are required.

I will select the most important special fields in the post and category tables to explain in detail, and the others will be mentioned as important.
post:
post_id
category_id varchar(10) This is the category used to index blog posts. The category_id here is also a string type, so multiple categories can be set for each blog post.

type varchar(20) This field is used to distinguish between post, article, and diary; it can also be set to postDraft, articleDraft;

visiable Whether the blog post is visible

Other commonly used fields include title, content, creation time, last modification time, number of views, number of comments, tags, allowed comments, and some reserved fields.

category:
parent, count_child_number, count_parent_number for future expansion
type can set the categories of photo albums, blog posts, and diaries respectively
Other common fields such as name, description, creation time, visibility
comment:
address user IP
user_agent User browser type

Other fields are omitted...
Server Architecture
PHP5.4.2 + MYSQL 5.523 + APACHE 2.2.22 + Windows NT ARIST-PC 6.1 build 7600 (Windows 7 Home Basic Edition) i586 (local)
Blog Architecture

Backend directory:

Backend directory description:

assert stores various resources js, css, image
class stores our classes, commonly used classes such as database operation classes, paging classes, and most of our models. . .
extention stores extensions such as mce's rich editor
config stores our configuration information
templates stores all templates (smarty is not used)
upload stores photos and other files
There will be some similar controllers in the admin root directory, such as index.php, post.php, article.php, photo.php

Let’s take a look at admin/config/config.php

复制代码 代码如下:
ini_set( "display_errors", true );
date_default_timezone_set( "Asia/Shanghai" );
// root and direcotry separate
define('DS', DIRECTORY_SEPARATOR);
define('ROOT', dirname(dirname(__FILE__)));

// database information
// need hash
define( "DB_USERNAME", "****" );
define( "DB_PASSWORD", '*****' );
define( "DB_NAME", "blog" );

// important directory
define( "CLASS_PATH", "classes" );
define( "TEMPLATE_PATH", "templates" );

// user imformation
define( "ADMIN_USERNAME", "admin" );
define( "ADMIN_PASSWORD", '$2a$08$wim8kpwHhAKa6MBSsGUMGOYfjkU1xvRKd4Fxwal.wj8dqFboCVSFawim8kpwHhAKa6MBSsGUMGO');
// hash and verified the password
function hasher($info, $encdata = false){
$strength = "08";
//if encrypted data is passed, check it against input ($info)
if ($encdata) {
if (substr($encdata, 0, 60) == crypt($info, "$2a$".$strength."$".substr($encdata, 60))) {
return true;
}else {
return false;
}
} else {
//make a salt and hash it with input, and add salt to end
$salt = "";
for ($i = 0; $i $salt .= substr("./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", mt_rand(0, 63), 1);
}
//return 82 char string (60 char hash & 22 char salt)
return crypt($info, "$2a$".$strength."$".$salt).$salt;
}
}

function __autoload($className) {
if (file_exists(ROOT . DS . 'classes' . DS . strtolower($className) . '.class.php')) {
require_once(ROOT . DS . 'classes' . DS . strtolower($className) . '.class.php');
} else {
/* Error Generation Code Here */
}
}



这里我们定义了一些基本常量,和几个函数。

__autoload() 函数加载 admin/class/ 中的所有类
用 hasher() 函数加密了一个 88位的 不可逆密码, 登录过程就是用config.php 中的常量和 hasher( ) 函数来进行验证。

来看我们的 admin/index.php 后台控制器 这个控制器主页 显示一些博客的相关数据

复制代码 代码如下:
require_once( "config/config.php" );
session_start( );
$action = isset( $_GET['action'] ) ? $_GET['action'] : "";
$username = isset( $_SESSION['username'] ) ? $_SESSION['username'] : "";

if ( $action != "login" && $action != "logout" && !$username ) {
login();
exit;
}

switch( $action ){
case "login" :
login( ) ;
break;

case "logout";
logout( );
break;

default :
admin( );
break;
}

function login( ){
$results['pageTitle'] = "Login Form";
// handle login
if( isset( $_POST['login'] ) ){
// we simple verify it from constant variable
// if we need to verify the user from database , do this later
// $user = new User ;
// $user->isValidateUser( $name, $password );

if ( $_POST['username'] == ADMIN_USERNAME && $_POST['password'] == hasher($_POST['password'], ADMIN_PASSWORD ) ){
// register a session data
$_SESSION['username'] = ADMIN_USERNAME ;
// location to admin page
header( "Location: index.php");
} else {
// Login failed: display an error message to the user
$results['errorMessage'] = "Incorrect username or password. Please try again.";
require( TEMPLATE_PATH . "/loginForm.php" );
}
} else {
require( TEMPLATE_PATH . "/loginForm.php" );
}
}

function admin( ){
$results['pageTitle'] = "Administrator Page";
require( TEMPLATE_PATH . "/admin.php" );
}

function logout( ){
$results['pageTitle'] = "Login Page";
unset( $_SESSION['username'] );
header( "Location: index.php ");
}



这个设计模式是从一个老外那里学的!

原理就是:
首先我们加载我们的config.php, 初始化session变量,获得 $action 这个重要变量的值;
然后我们判断 $action 和 $username 的值, 如果用户没有登录以及用户名为空,返回登录页面;
如 果用户正确输入了用户名和密码,则注册一个session 变量 $username,然后跳转到主页面 index.php, 这时我们会调用默认的 $action admin( ), 这个函数会加载一个模版admin.php;里面有个数组变量 $results['pageTitle'],以及我们的后台博客样式框架。
如果用户输入错了,则给出提示信息。

这个设计理念的核心就是, give {action} then {do something}
我们会在后面的代码中反复看到。

这个就是博客后台的框架样式,从博客园copy 来的,采用表格布局的,兼容的,可自定义其他样式的,简单的,实用的,可扩展的,完美后台框架。

这个样式在其他的浏览器中表现同样兼容,写这篇博文的时候,我已完成了部分功能。 下一篇:实现随笔,文章,日记 以及他们分类的CRUD。废话不多说了,上一篇有个核心概念就是 give action do something !

这篇我就用代码来解释这个概念是啥意思,先看我的 post.class.php . 这个文件是我们的数据层处理类。
 

简单介绍一下这个model 类,它继承了一个数据库基类来做crud 等常用操作, 每次初始化时就会初始化一个数据库对象 $db. 我们就用这个对象来操作我们的数据。
对于数据操作有2个重要方法 storePostFormValues( ) , storeDiaryFormValues( ),它们2个方法是数据流的开始。
还 有2个方法很有意思,addChildNumber( ), reduceChildNumber( ),  它们负责在插入或删除文档时的 一个暗箱操作。因为我的文档可以用多个分类,所以在操作文档的时候,要考虑到一个问题,就是 category 表中有个字段 记录了该分类下的 文档数量。所以要动态地改变这些数目的值。
下面配合 post.php 控制器,我们就可以开始我们数据的流程了(我的控制器还不是一个类,所以无法生成API文档。因为这还不是真正地MVC架构。)所以在MVC之前,这个也能更利于的理解MVC到底是神马东东,以及你自己如何去应用,写出自己的MVC。

以下的情形都是假设:

$action = "Give me a girlfriend from the sky!"; Let's pass in this controller and see what happens.

Copy code The code is as follows:
require_once( "config/config.php" );
session_start( );
$action = isset( $_GET['action'] ) ? $_GET['action'] : "";
$username = isset( $_SESSION['username'] ) ? $_SESSION['username'] : "";

if( !$username )
{
header("Location: index.php?action=login");
exit;
}

Here we have an important flow control statement switch, which means switch; so when the above $action = "Give me a girlfriend from the sky!"; when switch is passed in, there are only two possibilities, One is on and one is off. There is a bit of a pun here, and some students may see it. hey-hey!

Getting back to the topic: Take a look at how our switch switches these $actions on and off. It’s obvious that I won’t get a girlfriend from the sky, because there is no such switch in the controller, so I can only talk about the code.

Copy code The code is as follows:
switch( $action )
{
case "newPost" :
newPost( );
Break;

case "delete" :
         delete( ) ;
Break;

case "updatePost":
         updatePost( );
Break;

case "IsDraft":
listDraft( );
Break;

case "logout" :
Logout( );
Break;

case "isPost":
listPost( );
Break;

case "diffentCategoryPost":
        diffentCategoryPost( );
Break;

case "unCategory":
         unCategory( );
Break;

default:
listPost( );
Break;
}

Each switch should define a default switch, so that when we don’t have a girlfriend, we can ensure that we still have gay friends.
How to pass in action?
Let’s look at such a URL, which is the navigation of our background framework. Post.php?action=isPost This is a standard action. Each of our URLs is actually composed of these actions. You can also add other parameters to it. in our url, so that we can GET (get the values ​​of these variables) in the methods defined in the controller, and then we can have more control.
Okay, when this url reaches our controller, we receive the judgment and then turn on an isPost switch so that we can call the following methods. Think about turning on and off lights and computers. Switches are what we often do. .
Here we just changed the place.
OK. Let’s look at the following method for this switch.

Copy code The code is as follows:
function listPost( )
{
$results = array( );
$results['pageTitle'] = "Post List" ;
$results['path'] = "Essay";
// set the message
If ( isset( $_GET['error'] ) )
{
If ( $_GET['error'] == "InsertedFailed" ) $results['errorMessage'] = "Failed to add document";
If ( $_GET['error'] == "postDeleteFailed" ) $results['errorMessage'] = "Document deletion failed";
}
If ( isset( $_GET['status'] ) )
{
If ( $_GET['status'] == "changesSaved" ) $results['statusMessage'] = "The document is saved!";
If ( $_GET['status'] == "Deleted" ) $results['statusMessage'] = "The document has been deleted!";
If ( $_GET['status'] == "Inserted" ) $results['statusMessage'] = "You added a new document!";
If ( $_GET['status'] == "SaveToDraft" ) $results['statusMessage'] = "The document was saved to the draft box!";
}

// Browse documents by category
$db = MySQL::getInstance( );
$pagination = new Pagination;
$cat = new Category;
$results['categories'] = $cat->getCategoryList("post");

$pagination->countSQL = "select * from post where type = 'post' " ;
$db->Query( $pagination->countSQL );
$pagination->totalRecords = $db->RowCount( );
$records = $db->HasRecords( $pagination->rebuiltSQL( ) );
If( $records )
{
          $results['posts'] = $db->QueryArray( $pagination->rebuiltSQL( ) );
         require_once(TEMPLATE_PATH . "/post/post_list.php");
}
else
{
         require_once(TEMPLATE_PATH . "/post/post_list.php");
}

}

We define an array, $results = array(); The role of this array is obvious. It will save any data we get from the model, and can also save the special parameters of GET from the url. Then it will be displayed in the template included in our require_once(*****) below, and the path is defined in the path variable.

At the same time we will receive 2 prompt parameters,

error means that there is an error in the operation. It is inevitable for everyone, including computers. Everyone will make mistakes. The key is to admit it. Computers do a good job and they have the courage to admit their mistakes.

status; indicates status, which is a successful operation.

$pagination = new Pagination; This class is our pagination class. We pass in a total number to it, and then it will calculate the total number of pages. Each time it jumps to a page, it is equivalent to refreshing once, so everyone The method is to GET (obtain) the value of the page on the url in the constructor, so that we know the current page. At the same time, we regenerated the query statement, followed by a limiting statement, similar to limit $start (starting id), $offset (length); the principle is to give me 10 records starting from this id; I The setting is 10, you can also be more flexible.
$cat = new Category; This class will be discussed in detail later, and it is also a very important classification model. Here we simply obtain all categories under this type and display them in the sidebar. I have completed it. There are pictures and the truth!

In this way, our $results array stores all the data needed for our page. Okay, let's take a look at how our template is output.

复制代码 代码如下:
 
 
    
         <br>              博客后台管理
            
                       
        
    
            
                
                    
                
                
                    
                    
                
                
                    
                    
                
            

                        
操作

                    

                        

                

                
                                      if( isset( $results['statusMessage'] )){echo  $results['statusMessage'];}
                     if( isset( $results['errorMessage'] )){echo  $results['errorMessage'];}
                 ?>
                

 

    

         文章(主要用于转载,发布原创博文要通过“随笔”)
    

    
    
       if( isset( $results['posts'] )){
     echo             
                
                    
                    
                    
                                  
                    
                    
                

 EOB;
         foreach( $results['posts'] as $post ){
             $time = date("Y-m-d H:i:s", $post['create_time']);
             if( $post['status'] == "1" ){
                 $post['status']  = "发布";
             }    else {
                 $post['status']  = "未发布";
             }
             echo             
                
                
                
                
                
                    
            
 EOB;
         }
             echo "

                         标题
                    

                         发布

                         状态
                    

                         评论
                    

                         页面

                         浏览
                    

                         操作
                    

                         操作
                    
{$post['title']} ({$time}) {$post['status']} {$post['view_count']} {$post['comment_count']} 编 辑 删除
";               
             if( isset( $pagination) ){$pagination->createLinks( ) ;}
     } else {
         echo "当前无内容!";
     }

 ?>  

    

 


 

                        

                    

            

                
                
         
                    logout
                

                

            

            
                
                    
Statement
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
What are the advantages of using a database to store sessions?What are the advantages of using a database to store sessions?Apr 24, 2025 am 12:16 AM

The main advantages of using database storage sessions include persistence, scalability, and security. 1. Persistence: Even if the server restarts, the session data can remain unchanged. 2. Scalability: Applicable to distributed systems, ensuring that session data is synchronized between multiple servers. 3. Security: The database provides encrypted storage to protect sensitive information.

How do you implement custom session handling in PHP?How do you implement custom session handling in PHP?Apr 24, 2025 am 12:16 AM

Implementing custom session processing in PHP can be done by implementing the SessionHandlerInterface interface. The specific steps include: 1) Creating a class that implements SessionHandlerInterface, such as CustomSessionHandler; 2) Rewriting methods in the interface (such as open, close, read, write, destroy, gc) to define the life cycle and storage method of session data; 3) Register a custom session processor in a PHP script and start the session. This allows data to be stored in media such as MySQL and Redis to improve performance, security and scalability.

What is a session ID?What is a session ID?Apr 24, 2025 am 12:13 AM

SessionID is a mechanism used in web applications to track user session status. 1. It is a randomly generated string used to maintain user's identity information during multiple interactions between the user and the server. 2. The server generates and sends it to the client through cookies or URL parameters to help identify and associate these requests in multiple requests of the user. 3. Generation usually uses random algorithms to ensure uniqueness and unpredictability. 4. In actual development, in-memory databases such as Redis can be used to store session data to improve performance and security.

How do you handle sessions in a stateless environment (e.g., API)?How do you handle sessions in a stateless environment (e.g., API)?Apr 24, 2025 am 12:12 AM

Managing sessions in stateless environments such as APIs can be achieved by using JWT or cookies. 1. JWT is suitable for statelessness and scalability, but it is large in size when it comes to big data. 2.Cookies are more traditional and easy to implement, but they need to be configured with caution to ensure security.

How can you protect against Cross-Site Scripting (XSS) attacks related to sessions?How can you protect against Cross-Site Scripting (XSS) attacks related to sessions?Apr 23, 2025 am 12:16 AM

To protect the application from session-related XSS attacks, the following measures are required: 1. Set the HttpOnly and Secure flags to protect the session cookies. 2. Export codes for all user inputs. 3. Implement content security policy (CSP) to limit script sources. Through these policies, session-related XSS attacks can be effectively protected and user data can be ensured.

How can you optimize PHP session performance?How can you optimize PHP session performance?Apr 23, 2025 am 12:13 AM

Methods to optimize PHP session performance include: 1. Delay session start, 2. Use database to store sessions, 3. Compress session data, 4. Manage session life cycle, and 5. Implement session sharing. These strategies can significantly improve the efficiency of applications in high concurrency environments.

What is the session.gc_maxlifetime configuration setting?What is the session.gc_maxlifetime configuration setting?Apr 23, 2025 am 12:10 AM

Thesession.gc_maxlifetimesettinginPHPdeterminesthelifespanofsessiondata,setinseconds.1)It'sconfiguredinphp.iniorviaini_set().2)Abalanceisneededtoavoidperformanceissuesandunexpectedlogouts.3)PHP'sgarbagecollectionisprobabilistic,influencedbygc_probabi

How do you configure the session name in PHP?How do you configure the session name in PHP?Apr 23, 2025 am 12:08 AM

In PHP, you can use the session_name() function to configure the session name. The specific steps are as follows: 1. Use the session_name() function to set the session name, such as session_name("my_session"). 2. After setting the session name, call session_start() to start the session. Configuring session names can avoid session data conflicts between multiple applications and enhance security, but pay attention to the uniqueness, security, length and setting timing of session names.

See all articles

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

Powerful PHP integrated development environment

Dreamweaver Mac version

Dreamweaver Mac version

Visual web development tools

VSCode Windows 64-bit Download

VSCode Windows 64-bit Download

A free and powerful IDE editor launched by Microsoft

Atom editor mac version download

Atom editor mac version download

The most popular open source editor

SecLists

SecLists

SecLists is the ultimate security tester's companion. It is a collection of various types of lists that are frequently used during security assessments, all in one place. SecLists helps make security testing more efficient and productive by conveniently providing all the lists a security tester might need. List types include usernames, passwords, URLs, fuzzing payloads, sensitive data patterns, web shells, and more. The tester can simply pull this repository onto a new test machine and he will have access to every type of list he needs.