Go to comments

PHP 小项目

一、创建数据表

帖子表 thread

id主键 tid

用户名 username

标题 title

内容 content

发布时间 pubtime


回复表reply

id主键 rid

被回复贴的id tid

回复的用户名 username

回复的内容 content

回复时间 reptime

create database tieba charset utf8;

use tieba;

create table thread(
	tid int not null auto_increment primary key,
	username varchar(20) not null default '',
	title varchar(30) not null default '',
	content text,
	pubtime int unsigned not null default 0
)engine myisam charset utf8;

create table reply(
	rid int not null auto_increment primary key,
	tid int not null default 0,
	username varchar(20) not null default '',
	content text,
	reptime int unsigned not null default 0
)engine myisam charset utf8;

show tables;

解决这四个问题

1.每个页面操作数据库时,都要mysql_connect链接一下,如何代码重用?

2.发布信息的时候,用户有可能发一些恶意的sql注入代码,转义用户提交的的数据

3.封装查询数据库函数

4.一个变量没有声明,直接判断时,出现NOTICE提醒

二、include/require详解

include

require

include_once

require_once


include和require完全一样,相当于把conn.php的代码复制粘贴过来

include( './conn.php' );

require( './conn.php' );


可以用相对路径,也可以用绝对路径

include( 'd:/xampp/htdocs/conn.php' );

require( './conn.php' );

PS: 在window下路径可用斜线或反斜线都没有问题,在liunx下只能用正斜线 /


include和require不同

include是包含的意思,找不到包含文件时会报Waring警告,程序继续往下执行

require是必须的意思,找不到包含文件时报Fatal致命错误,程序停止执行


总结:

在包含文件上include和require的功能是一样的,区别只在报错方式不同。

once在英语里有"仅一次"的意思

include_once和inclued的区别

require_once和require的区别


conn.php文件

<?php

    $age ++;

?>

每include一次$age++语句就执行一次

$age = 1;

include('./conn.php');
echo $age,'<br/>'; // 2

include('./conn.php');
echo $age,'<br/>'; // 3

include('./conn.php');
echo $age,'<br/>'; // 4

include_once无论包含多少次,每次打印都是2

$age = 1;

include_once('./conn.php');
echo $age,'<br/>'; // 2

include_once('./conn.php');
echo $age,'<br/>'; // 2

include_once('./conn.php');
echo $age,'<br/>'; // 2

加onec后在包含时系统会进行判断,如果已经包含则不会再次包含


include和require在效率声明没有什么区别

比如是系统配置,缺少了网站运行不了,自然用require

如果是某一段统计代码,少了对网站只是少了一个功能,可以用include

include和require是重要性上的考量,没有效率上的区别。


include和require加onec则是效率上的区别

加_once虽然系统帮我们只加载一次,但系统判断导致系统效率降低

因此,应该在开发之初,就把目录结构整理好,尽量不要用_once的情况

include和require还能返回值用

A.php文件

<?php

    return array('a', 'b', 'c');

?>

利用include和require返回被包含页面的值(也不能算偏门的用法)

1. 被包含页面A中 return value

2. 包含页面B中 $v = include('A.php')

3. $v被赋值为value

$arr = include('./conn.php');

print_r($arr); // Array ( [0] => a [1] => b [2] => c )

这个用法在网站做配置文件时,会偶尔碰到比如thinkphp的配置文件(thinkphp/conf/convention.php文件里面,return的一个大数组)

三、魔术引号与递归转义

addslashes() 可以对一个变量转义

POST是一个数组,可能有多个单元,写一个方法可以对数组的每一个单元进行转义

$_POST = array('name'=>'张三', 'age'=>29, 'gender'=>'male');

PS: mysql_real_escape_string也可以进行转义


插播一个小题目

$arr = array(1, 2, 3, 4) 循环后变成 $arr = array(2, 4, 6, 8)

$arr = array(1, 2, 3, 4);

foreach($arr as $k=>$v){
	$arr[$k] = $v*2;
}

print_r($arr);

回到$_POST上来,要循环$_POST做转义,is_string()函数判断如果是字符串就进行转义

$_POST = array('name'=>'张三"', 'age'=>29, 'gender'=>'"male"');

foreach($_POST as $k=>$v){

	if(is_string($v)){
		$_POST[$k] = addslashes($v);
	}

}

print_r($_POST); // Array ( [name] => 张三\" [age] => 29 [gender] => \"male\" ) 双引号被转义了

但是多维数组,数组第一层单元被转义了,数组第二层里面的单元没有被转义

$_GET = ['id'=>5, 'nationality'=>'"中国"', 'info'=>['user'=>'"Vivian"', 'gender'=>'"fomale', 'area'=>'"衡水"']];

foreach($_GET as $k=>$v){
	if(is_string($v)){
		$_GET[$k] = addslashes($v);
	}
}

print_r($_GET); // Array ( [id] => 5 [nationality] => \"中国\" [info] => Array ( [user] => "Vivian" [gender] => "fomale [area] => "衡水" ) )

用递归的方法,只要是数组就进行待处理

bool array_walk_recursive(array &$array, callable $callback, mixed $userdata = null); 

array_walk_recursive() 函数只有一个功能,递归的把数组每个单元走一遍,至于怎么处理,在回调函数里自己写

$_GET = ['id'=>5, 'nationality'=>'"中国"', 'info'=>['user'=>'"Vivian"', 'gender'=>'"fomale', 'area'=>'"衡水"']];

function call_addslashes(&$val, $key){
	//echo $key,'=>',$val,'<br/>';
	$val = addslashes($val);
}

array_walk_recursive($_GET, 'call_addslashes');

print_r($_GET); // Array ( [id] => 5 [nationality] => \"中国\" [info] => Array ( [user] => \"Vivian\" [gender] => \"fomale [area] => \"衡水\" ) )

PHP中魔术引号的概念

1.在php.ini文件

2. magic_quotes_gpc = Off/On 中设置为On

3. 然后重启Apache

魔术引号开启时 $_GET, $_POST, $COOKIE 都会被系统自动转义


动态的开启魔术引号

ini_set('magic_quotes_gpc', 'Off');

ini_set('magic_quotes_gpc', 'On');


开启魔术引号后系统自动转义,再经过addslashes函数转义就多转义了一次

想要合理的转义,先判断魔术引号有没有开启,开启了就不要转义了

用 magic_quotes_gpc() 函数判断魔术引号有没有开启

get_magic_quotes_gpc()函数的作用就是得到环境变量magic_quotes_gpc的值。切记在PHP6中删除了magic_quotes_gpc这个选项,所以PHP6中这个函数已经不复存在了。

https://blog.csdn.net/weixin_32724679/article/details/115649271


https://blog.csdn.net/allanshi1986008/article/details/101127750

if(get_magic_quotes_gpc()){

	echo '魔术引号开了';

}else{

	echo '魔术引号没有开,需要自己转义';

}

// var_dump(get_magic_quotes_gpc()); // bool(false)

因为初学者的课程没有涉及到函数递归,燕十八老师用下面的方式转义

if(!get_magic_quotes_gpc()){

	function call_addslashes(&$val, $key){
		$val = addslashes($val);
	}

	array_walk_recursive($_GET, 'call_addslashes');
	array_walk_recursive($_POST, 'call_addslashes');
	array_walk_recursive($_COOKIE, 'call_addslashes');

}

燕十八老师的课程受益很多,对下面的这个方法认识更深入了,原来递归的意义是处理多维数组的

function daddslashes($string) {

	if (! get_magic_quotes_gpc ()) {
		if (is_array ( $string )) {
			foreach ($string as $key => $value) {
				$string [$key] =  daddslashes($value);
			}
		} else {
			$string = addslashes ($string);
		}
	}
	return $string;

}


$_GET = ['id'=>5, 'nationality'=>'"中国"', 'info'=>['user'=>'"Vivian"', 'gender'=>'"fomale', 'area'=>'"衡水"']];


print_r(daddslashes($_GET));

四、错误设置

变量$a没有声明,直接相加值为null,相加时候null当成0来计算,结果等于3

但是出现Notice提示 Notice: Undefined variable: a in …… Notice是注意的意思

$b = 3;

echo $a + $b; // 3

为什么要调错误级别?

PHP针对严重级别不同的错误,给予不同的提示

我们在开放中,为了程序的规范性,报错级别调的比较高

Notice级别的也报出来,有助于我们快速的定位错误和代码规范


但是在产品上线后,网站运营过程中,就不宜报这么多错误提示

1.这种错误给客户的印象不好

2.在报错时,把网站的绝对路径,如D:\xampp\htdocs\……都显示出来了,增加被攻击的风险。有人故意打一个不存在的路径,探测服务器上文件的位置

因此,在网站上线后,就应该让报错级别调低,少报错甚至不报错,就一个空白页面

如何调报错级别?

方法一:在php.ini文件里配置,修改error_reporting 选项

方法二:可以在PHP页面里用 error_reporting() 函数来修改

具体怎么修改?

打印系统自定义内部常量 E_ALL 结果是一个整形的值

echo E_ALL; // 32767

错误级别是用二进制的值来表示的

从左到右,每一位上的1代表一种错误基本,每一位上都是1代表全部错误都报

0000 0000 0000 001 致命错误 fatal error

0000 0000 0000 010 警告错误 warning 

0000 0000 0001 000 注意 NOTICE


报这上面fatal、warning、NOTICE 这三个错误出来,其它的错误不报,二进制1011转十进制是11

error_reporting(11);

变量$a未声明

error_reporting(11);

$b = 3;
echo $a + $b; // NOTICE报出来了

数学里除数不能为0,因此报错

error_reporting(11);

echo 3/0; // Warning: Division by zero in ……

Fatal致命错误,打一个不存在的函数

echo xdadadade(); // Fatal error: Call to undefined function xdadadade() in……


不要抱NOTICE错误,二进制11转十进制是3

error_reporting(3);

$b = 3;

echo $a + $b; // 3


任何错误都不报

error_reporting(0);

echo dadadade(); // Fatal

echo $a + $b; // 这里应该输出0,但是不执行了,上面是Fatal致命错误,就不往下执行了

echo 3/0;


报所有的错误的数字是多少?

不必通过二进制取算了,系统把各个级别的值,用系统的常量代替了

E_ERROR       值是1

E_WARNING 值是2

E_PARSE   

E_NOTICE      值是8

E_ALL             所有的错误都报


报所有错误

error_reporting(E_ALL);


除了NOTICE其它都报,先把所有错误都报出来,位运算符取反~ &与

error_reporting(E_ALL & ~E_NOTICE );

把warning也加上,wariing也不报了,

error_reporting(E_ALL & ~E_NOTICE & ~E_WARNING);


开发时候,声明一DEBUG模式

// define('DEBUG', true); // 网站上线把这行语句屏蔽

if(defined('DEBUG')){
	error_reporting(E_ALL); // 检测到处于开发模式 
}else{
	error_reporting(0);
}

五、函数封装

取多行数据

/**
 * 取多行数据
 * array getAll($sql, $conn)
 * @param {string}   $sql
 * @param {resource} $conn
 * return array/false
 *
 */

$conn = mysql_connect('localhost', 'root', '');
if(!$conn){
	echo '链接错误';
}
mysql_query('set names utf8', $conn);
mysql_query('use db_orange');


function getAll($sql, $conn){
	// 验证$conn通道发送sql
	// 再while循环,取出每一行
	// 装到一个二维数组,再返回
	
	$rs = mysql_query($sql, $conn);
	
	if(!$rs){// 查询失败
		return false;
	}
	
	$result = array();
	
	while($row = mysql_fetch_assoc($rs)){
		$result[] = $row;
	}
	
	return $result;
}

$sql = 'select id, name, age, groupid from regist';

$arr = getAll($sql, $conn);

print_r($arr);

取一行数据

/**
 * 取一行数据
 * @param {string}   $sql语句
 * @param {resource} $conn资源
 * return array/false
 */
$conn = mysql_connect('localhost', 'root', '');
if(!$conn){
	echo '链接错误';
}
mysql_query('set names utf8', $conn);
mysql_query('use db_orange');

function getRow($sql, $conn){

	$rs = mysql_query($sql, $conn);

	if(!$rs){
		return false;
	}

	return mysql_fetch_assoc($rs);

}

$sql = 'select id, name, age, groupid from regist where id = 9';

$row = getRow($sql, $conn);

print_r($row);

一共有多少条数据

mysql_num_rows()把所有行都取出来后,有多少条数据,耗费资源

$sql = 'select count(*) from regist'; 省资源

$conn = mysql_connect('localhost', 'root', '');
if(!$conn){
	echo '链接错误';
}
mysql_query('set names utf8', $conn);
mysql_query('use db_orange');

function getOne($sql, $conn){

	$rs = mysql_query($sql, $conn);

	if(!$rs){
		return false;
	}

	return mysql_fetch_row($rs)[0];

}

$sql = 'select count(*) from regist';

echo getOne($sql, $conn);


mysql_select_db('db_orange', $conn) === mysql_query('use db_orange', $conn)

mysql_set_charset() 发送字符集语句

六、时间戳

为什么用时间戳来储存时间?

1). 便于存储,2038年之前的时间戳,都没超过40亿,因此用4个字节的int型就可以存储了

2). 时间戳就是数学上的一个值,没有歧义

     如果用格式,中国人喜欢2012年01月01日,西方有的国家喜欢用 01月/01日/2012年 00:00:00

     用时间戳就没有这些不同

3). 时间戳虽然不便于给人看,但是时间戳便于给机器运算,便于比较时间差


例子:

计算出24小时内发布的帖子

1). 发布时间戳pubtime

     当前时间戳current

2). b = current - 24 * 3600

3). pubtime >= b


date()函数格式化时间戳

$time = time();

echo date('Y', $time); // 2012

echo date('y', $time); // 12,2012的后两位,用两位数表示年

echo date('M', $time); // Aug,用英语表示月份

echo date('m', $time); // 08,用数字表示月份

echo date('d', $time); // 16,表示16号

echo date('Y-m-d', $time); // 2021-08-16

echo date('Y/m/d', $time); // 2021/08/16

echo date('Y m d', $time); // 2021 08 16

echo date('m/d/Y', $time); // 08/16/2021,(月/日/年)

echo date('Y/m/d H : i', $time); // 2012/08/16 18 : 52


strtotime()函数,把字符串形式时间,转化成时间戳

$borth = '1985-05-17';

echo strtotime($borth); // 485128800

从现在当前时间,退回1天前的时间戳

echo strtotime('-1 day'); // 

echo time() - strtotime('-1 day'); // 86400,24小数的秒数

退回到一周前的时间戳

echo strtotime('-7 day'),'<br/>'; // 1628615676

echo strtotime('-1 week'); // 1628615676

七、项目

1、目录结构

|-itemFolter

          |--include

                    |--config.inc.php

                    |--init.php

                    |--mysql.func.php

                    |--string.func.php

          |--style

                    |--base.css     

                    |--result.css

          |--tie.php

          |--pubaction.php

          |--repaction.php

          |--index.php

2、代码

include/config.inc.php

/*---------------------------------------------------------------------------------------------
	公共配置文件
	内容:网站的一些运行参数
	意义:当我们的网站,迁移到另一台服务器时候,只需要修改此配置文件就可以了
-----------------------------------------------------------------------------------------------*/   

$_CFG = array();

$_CFG['host'] = 'localhost';
$_CFG['user'] = 'root';
$_CFG['passwd'] = '';
$_CFG['db'] = 'tieba';
$_CFG['charset'] = 'utf8';

define('DEBUG', true); // true网站处于开发环境


include/init.php

/*---------------------------------------------------------------------------------------------
	初始化脚本
	网站运行先找init文件,把环境检查初始化一遍
	作用:
	比如,检测运行环境,并进行响应的处理,比如魔术引号有没有开,并对$_POST数据进行处理
	比如,判断网站当前是开发环境,还是生产环境,设置合理的错误报告
-----------------------------------------------------------------------------------------------*/ 

// 定义根目录常量 
// define('ROOTDIR', 'd:/xampp/htdocs/PHP5/mysql_article/');
define('INC', str_replace("\\", '/', dirname(__FILE__) ) );
define('ROOT', str_replace("\\", '/', substr(INC,0,-8) ) );

require(ROOT.'/include/config.inc.php');
require(ROOT.'/include/mysql.func.php');
require(ROOT.'/include/string.func.php');


// 检测当前是开发环境,还是生产环境
if(defined('DEBUG')){
	error_reporting(E_ALL);
	error_reporting(E_ALL ^ E_DEPRECATED); // 避免这句 Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in
}else{
	error_reporting(0);
}


// 检测魔术引号是否开启,转义字符串
$_POST = daddslashes($_POST); 
$_GET = daddslashes($_GET);
//print_r($_POST);

// 链接数据库
$conn = mysql_connect($_CFG['host'], $_CFG['user'], $_CFG['passwd']);

if(!$conn){
	echo '链接失败';
	exit;
}

mysql_query('set names '.$_CFG['charset'], $conn); 

$rs = mysql_select_db($_CFG['db'], $conn);

if(!$rs){
	echo '请检查选择的数据库';
	exit;
}


include/mysql.func.php

/*---------------------------------------------------------------------------------------------
	Mysql的相关处理函数
-----------------------------------------------------------------------------------------------*/ 

/**
 * 取多行数据
 * array getAll($sql, $conn)
 * @param {string}   $sql
 * @param {resource} $conn
 * return array/false
 *
 */

function getAll($sql, $conn){
	
	$rs = mysql_query($sql, $conn);
	
	if(!$rs){
		return false;
	}
	
	$result = array();
	
	while($row = mysql_fetch_assoc($rs)){
		$result[] = $row;
	}
	
	return $result;
}



/**
 * 取一行数据
 * @param {string}   $sql语句
 * @param {resource} $conn资源
 * return array/false
 */

function getRow($sql, $conn){

	$rs = mysql_query($sql, $conn);

	if(!$rs){
		return false;
	}

	return mysql_fetch_assoc($rs);

}


// 一共有多少条数据
function getOne($sql, $conn){

	$rs = mysql_query($sql, $conn);

	if(!$rs){
		return false;
	}

	return mysql_fetch_row($rs)[0];

}


include/string.func.php

/**
 * @param {mixed} 
 * return array
 */
 
function daddslashes($string) {

	if (! get_magic_quotes_gpc ()) {
		if (is_array ( $string )) {
			foreach ($string as $key => $value) {
				$string [$key] =  daddslashes($value);
			}
		} else {
			$string = addslashes ($string);
		}
	}

	return $string;
}


style/base.css

.top{
	margin-bottom: 32px;
    height: 32px;
    border-bottom: 1px solid #ebebeb;
    overflow: hidden;
}
.top a{
	font-size: 13px;
	display: inline-block;
	margin-left: 42px;
	line-height: 34px;
	color: #333;
	text-decoration: underline;
}

.title_name_h2{
	font-size: 24px;
	margin-bottom: 10px;
}
.pub_form,
.thread,
.title_name_h2,
.reply_form,
.con_author,
.con_time,
.con_content,
.replaylist{
	margin-left: 42px;
}


/* thread */
.thread{
	margin-bottom: 40px;
}

.thread li{
	width: 900px;
	height: 38px;
	line-height: 38px;
	border-bottom: 1px dotted #e4e6eb;
}

.thread .pull_left{
	float: left;
}
.thread .pull_right{
	float: right;
}
.thread_title a{
	font-size: 14px;
	color: #2d64b3;
}

.thread_slash,
.thread_date,
.thread_reply,
.thread_del{
	font-size: 12px;
	margin-left: 5px;
	color: #999;
}

.con_content{
	padding-top: 10px;
	width: 900px;
	line-height: 22px;
}

.pub_form,
.reply_form{
	line-height: 38px;
}

.con_content{
	margin-bottom: 20px;
}
.replaylist{
	margin-bottom: 30px;
}
.replaylist li{
	width: 900px;
	height: 38px;
	line-height: 38px;
	border-bottom: 1px dotted #e4e6eb;
}

.submit{
	border: none;
	height: 30px;
	line-height: 30px;
	width: 120px;
	text-align: center;
	background-color: #4C4C4C;
	color: #FFFFFF;
}

.footer{
	height: 40px;;
}


style/result.css

/* http://meyerweb.com/eric/tools/css/reset/ 
   v2.0 | 20110126
   License: none (public domain)
*/

html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed, 
figure, figcaption, footer, header, hgroup, 
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
	margin: 0;
	padding: 0;
	border: 0;
	font-size: 100%; /* 可以理解为1em */
	font: inherit;
	vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure, 
footer, header, hgroup, menu, nav, section {
	display: block;
}
body {
	line-height: 2; /* 行高是1 */
	
	font-size: 12px;
	font-family: "Helvetica Neue",Helvetica,Arial,sans-serif;
	color: #333;
	line-height: 22px;
}
ol, ul {
	list-style: none;
}
blockquote, q {
	quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
	content: '';
	content: none;
}
table {
	border-collapse: collapse;
	border-spacing: 0;
}

* {
    box-sizing: content-box;
}
li{
	list-style: none;
}
.clearfix::after{
	content:"";
	display: block;
	clear: both;
}
a{
	text-decoration:none
}


index.php

<?php
require('./include/init.php');

$sql = 'select tid, title, username, pubtime from thread order by pubtime desc';

if(!$list = getAll($sql, $conn)){
echo $sql,'<br/>';
exit('getAll函数出现问题');
}
// print_r($list);


// 最笨的方法,挨个循环帖子列表,挨个取帖子的回复数
/*--------------------------------------------------------------
foreach($list as $k=>$v){
// echo $v['tid'],'<br/>';
$sql = 'select tid from reply where tid='.$v['tid'];
// echo count(getAll($sql, $conn)),'<br>';

// $v是临时变量,不能影响$list数组
//$v[$k]['rnum'] = count(getAll($sql, $conn));
$list[$k]['rnum'] = count(getAll($sql, $conn));
}
--------------------------------------------------------------*/


// 稍微进步一点的方法,用sql语句,count统计函数
// 没有进步,因为是两张表不会联查,用了被笑话的1+n模式
/*--------------------------------------------------------------
foreach($list as $k=>$v){
$sql = 'select count(*) from reply where tid='.$v['tid'];
// echo getOne($sql, $conn),'<br/>';
$list[$k]['rnum'] = getOne($sql, $conn);
}
--------------------------------------------------------------*/


// 用一条sql语句就完成了所有
/*--------------------------------------------------------------
// $sql = 'select tid,username,title,pubtime, (select count(*) from reply where reply.tid=thread.tid) as rnum from thread';
$sql = 'select tid,username,title,pubtime, (select count(*) from reply where reply.tid=thread.tid) as rnum from thread order by pubtime desc';

if(!$list = getAll($sql, $conn)){
echo $sql,'<br/>';
exit('getAll函数出现问题');
}
//print_r($list);
--------------------------------------------------------------*/


?>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>贴吧</title>
<link rel="stylesheet" href="style/result.css">
<link rel="stylesheet" href="style/base.css">
</head>
<body>
<div>
<!-- <a href="index.php">贴吧</a> -->
</div>

<h2>看贴</h2>

<ul>
<!-- 手册:语言参考 => 基本语法 => 从HTML中分离 -->
<?php foreach($list as $k=>$v){ ?>

<li>

<span class="pull_left thread_title">
<a href="tie.php?tid=<?php echo $v['tid'];?>"><?php echo $v['title'];?></a>
</span>

<span class="pull_left thread_date">
<?php
// 今天凌晨的时间戳
$ling = date('Y-m-d', time()); // 2012-10-17 0:0:0
$tmp = strtotime($ling); // 转换成时间戳

// 凌晨以后发帖子,也就是今天发的帖子
if($v['pubtime'] >= $tmp){
echo date('H:i', $v['pubtime']);
}else{
echo date('m-d', $v['pubtime']);
}
?>
</span>

<!-- <span class="pull_left thread_slash">/</span> -->

<span class="pull_right thread_reply"><?php // echo $v['rnum'];?></span>

<!-- <span class="pull-right thread_del">del</span> -->

</li>

<?php } ?>
</ul>

<h2>发表新贴</h2>

<div>
<form action="pubaction.php" method="post">
<p>用户名称:<input type="text" name="username" value="长空无忌"></p>
<p>文章标题:<input type="text" name="title"></p>
<p><textarea name="content" style="width: 900px;height: 100px;"></textarea></p>
<p><input type="submit" name="sub" value="提交"></p>
</form>
</div>

<div></div>
</body>
</html>


pubaction.php

/*---------------------------------------------------------------------------------------------
	pubaction
	publisher出版人(或机构)发行人(或机构)
	
	trim() 去两端空格
-----------------------------------------------------------------------------------------------*/

require('./include/init.php');

// 第一步:接收数据
// print_r($_POST);



// 第二步:检测数据
if(trim($_POST['username']) == ''){
	exit('用户名不能为空');
}

if(trim($_POST['title']) == ''){
	exit('标题不能为空');
}

if(trim($_POST['content']) == ''){
	exit('内容不能为空');
}

// 第三步:拼接sql语句
echo $sql = "insert into thread (username, title, content, pubtime) values('".$_POST['username']."', '".$_POST['title']."', '".$_POST['content']."', ".time().")";



// 第四部:执行sql

/*---------------------------------------------------------------------------------------------
	mysql_insert_id()函数
	返回表中 auto_increment列刚刚产生的最大值
	插入后要立即调用该函数,否则可能得到意外的结果
	请注意,表中必须有auto_increment列,才能用这个函数,否则只返回0
---------------------------------------------------------------------------------------------*/

if(!mysql_query($sql, $conn)){
	echo '发帖失败';
	exit;
}else{
	
	$tid = mysql_insert_id($conn);

	$script = <<<EOT
			<script type="text/javascript">
				alert('发帖成功');
				window.location.href = 'tie.php?tid=$tid';
			</script>
EOT;
	echo $script;
}


repaction.php

require('./include/init.php');

// 第一步:接收数据
print_r($_POST);


// 第二步:检测数据
$tid = $_POST['tid'] + 0;

if(!$tid || trim($_POST['username']) == '' || trim($_POST['content']) == ''){
	exit('三项中,有一项不正确,数据非法');
}

// 第三步:拼接sql语句  == '' 
$sql = "insert into reply (tid, username, content, reptime) values ('".$_POST['tid']."', '".$_POST['username']."', '".$_POST['content']."', ".time().")";


// 第四部:执行sql
if(!mysql_query($sql, $conn)){
	echo $sql,'<br/>';
	exit('回复失败');
}else{

	$script = <<<EOT
			<script type="text/javascript">
				alert('回复成功');
				window.location.href = 'tie.php?tid=$tid';
			</script>
EOT;
	echo $script;
}


tie.php

<?php
require('./include/init.php');


if(empty($_GET['tid'])){
exit('tid非法');
}

$tid = $_GET['tid'] + 0;

$sql = 'select * from thread where tid ='.$tid;

$thread = getRow($sql, $conn);

// 如果取出来的值空,防止tid=9999
if(empty($thread)){
exit('tid非法');
}
// print_r($thread);


// 继续取帖子的回复
$sql = 'select * from reply where tid ='.$tid;

// 回复可能是一条或多条,用getAll()来取
$reply = getAll($sql, $conn);
// print_r($reply);

$num = count($reply); // 帖子的回复数

?>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" href="style/result.css">
<link rel="stylesheet" href="style/base.css">
<title><?php echo $thread['title'];?></title>
</head>
<body>
<div>
<a href="index.php">贴吧</a>
</div>

<h2><?php echo $thread['title'];?></h2>
<p>作者:<?php echo $thread['username'];?></p>
<p>时间:<?php echo date('Y-m-d H:i', $thread['pubtime']);?></p>
<p>有 <span style="color: orange;"><?php echo $num;?></span> 条回复</p>
<div><?php echo $thread['content'];?></div>


<!-- 回复从这开始 -->
<ul>
<?php foreach($reply as $k=>$v){ ?>

<li><?php echo $v['username'];?> : <?php echo $v['content'];?></li>

<?php }?>
<!-- 回复 end -->
</ul>

<h2 class="title_name_h2 cleafix">REPLY</h2>

<div class="reply_form cleafix">
<form action="repaction.php" method="post">
<input type="hidden" name="tid" value="<?php echo $_GET['tid'];?>">
<p>用户名称:<input type="text" name="username" value="专业回复"></p>
<p><textarea name="content" style="width: 900px;height: 100px;"></textarea></p>
<p><input type="submit" name="submit" value="提交"></p>
</form>
</div>

<div></div>

</body>
</html>



Leave a comment 0 Comments.

Leave a Reply

换一张