現在「salvation channel」 という題目(仮名)でSNSのサイトを作成しています。
プログラム言語は[PHP]とデータベースは[MySQL]です。
いまのところ
主な機能は
1)認証システムは完成しました。
2)名前でログインして、質問を書きこんだり、質問に回答したりできます。
そのファイルシステムは以下のアドレスからダウンロードできます。
※6-14-3.zipファイルは以下のプログラムと同じです。もし試される場合は
zip〜が楽です。
以上の2件はできますが目標とするSNSは
「ヤフー知恵袋」みたいにSNSを制作したいです。
各「ユーザー」が[ログイン]すると「ユーザー」の
3)Q&Aの履歴
4)「質問のcategory」毎に分類して、Q&Aができるシステム
5)質問した内容を「検索できる」機能
以上「3)4)5)」までの3件ですが、現在作成した以下のプログラムに取り入れたいです。
制作していただけないでしょうか?
また有料でしたら、「90日間の補償費込み」でしたら「どれぐらいの金額」でしたら作成していただけますか?
以上よろしくお願いいたします。
以下は「salvation channel」(仮名)というSNSです。
「ファイルシステム」ですが、「階層型のファイルシステム」
の構造図です。
O6-14-3/join
├ member_picture //画像のアップロードデレクトリ
├index.php //会員登録用画面を作る
├check.php //周辺の画面と処理を作る
└thanks.php //ユーザー登録完了画面
O6-14-3
├
style.css//背景など
├
view.php //個別画像を作る
├
login.php //ログイン処理
├
logout.php //ログアウト処理
├
index.php //投稿画面を作る
├
dbconnect.php //データベース接続のプログラム
└
delete.php //削除画面と削除機能を作る
最初に会員登録画面から作ります。そのアプリケーションフォルダーとして「post」を作り、
その中に、会員登録用のプログラム用「join」フォルダを作成します。
----------------------------
O6-14-3/join/member_picture //画像のアップロードデレクトリ
---------------------------
----------------------
O6-14-3/join/index.php//会員登録用画面を作る
----------------------
<?php
require('../dbconnect.php');
//write a program to check
session_start();
if (!empty($_POST)) {
//
エラー項目の確認
if
($_POST['name'] == '') {
$error['name']
= 'blan2';
}
//Add
image check function
if
(strlen($_POST['password']) < 4) {
$error['password']
= '3';
}
if
($_POST['password'] == '') {
$error['password']
= 'blank';
}
$fileName
= $_FILES['image']['name'];
if
(!empty($fileName)) {
$ext
= substr($fileName, -3);
if
($ext != 'jpg' && $ext != 'gif') {
$error['image']
= 'type';
}
}
Check
account focus
//
アカウントの重複を確認する
if
(empty($error)) {
$member
= $db->prepare('SELECT COUNT(*) AS cnt FROM members WHERE name=?');
$member->execute(array($_POST['name']));
$record
= $member->fetch();
if
($record['cnt'] > 0) {
$error['name']
= 'duplicate';
}
}
if
(empty($error)) {
//
画像をアップロードする
$image
= date('YmdHis') . $_FILES['image']['picture'];
move_uploaded_file($_FILES['image']['tmp_name'],
'member_picture/' . $image);
$_SESSION['join']
= $_POST;
$_SESSION['join']['image']
= $image;
header('Location:
check.php'); exit();
}
}
//Add rewrite functionality
// 書き直し
if ($_REQUEST['action'] == 'rewrite') {
$_POST
= $_SESSION['join'];
$error['rewite']
= true;
}
?>
<!DOCTYPE html>
<html lang="ja">
<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.css" />
</head>
<body>
<div id="wrap">
<div id="head">
<h1>会員登録</h1>
</div>
<div id="content">
<!-- Create a screen for member
registration-->
Create HTML for registration screen
-->
<p>次のフォームに必要事項をご記入ください。</p>
// 登録画面のHTMLを作成する
<form action=""
method="post" enctype="multipart/form-data">
<dl>
<!--
Create a nickname check function -->
<dt>ニックネーム<span class="required">必須</span></dt>
<dd>
<!--
すべてのアイテムにチェック処理を追加します
-->
<input
type="text" name="name" size="35"
maxlength="255" value="<?php echo
htmlspecialchars($_POST['name'], ENT_QUOTES, 'UTF-8'); ?>" />
<?php
if ($error['name'] == 'blank'): ?>
<p
class="error">* ニックネームを入力してください</p>
<?php endif; ?>
<?php
if ($error['name'] == 'duplicate'): ?>
<p
class="error">* 指定されたネームはすでに登録されています</p>
<?php
endif; ?>
<dt>パスワード<span
class="required">必須</span></dt>
<dd>
<input
type="password" name="password" size="10"
maxlength="20" value="<?php echo
htmlspecialchars($_POST['password'], ENT_QUOTES, 'UTF-8'); ?>" />
<?php
if ($error['password'] == 'blank'): ?>
<p
class="error">* パスワードを入力してください</p>
<?php
endif; ?>
<?php
if ($error['password'] == 'length'): ?>
<p
class="error">* パスワードは4文字以上で入力してください</p>
<?php
endif; ?>
</dd>
//
display an error message
<dt>写真など</dt>
<dd>
<input
type="file" name="image" size="35"
value="test" />
<?php
if ($error['image'] == 'type'): ?>
<p
class="error">* 写真などは「.gif」または「.jpg」の画像を指定してください</p>
<?php
endif; ?>
<?php
if (!empty($error)): ?>
<p
class="error">* 恐れ入りますが、画像を改めて指定してください</p>
<?php
endif; ?>
</dd>
</dl>
<div><input
type="submit" value="入力内容を確認する" /></div>
</form>
</div>
</body>
</html>
----------------------
O6-14-3/join/check.php //周辺の画面と処理を作る
----------------------
<?php
//View entered information
session_start();
require('../dbconnect.php');
if (!isset($_SESSION['join'])) {
header('Location:
index.php');
exit();
}
//register in the database
if (!empty($_POST)) {
//
登録処理をする
$statement
= $db->prepare('INSERT INTO members SET name=?, password=?, picture=?,
created=NOW()');
echo
$ret = $statement->execute(array(
$_SESSION['join']['name'],
sha1($_SESSION['join']['password']),
$_SESSION['join']['image']
));
unset($_SESSION['join']);
header('Location:
thanks.php');
exit();
}
?>
<!DOCTYPE html>
<html lang="ja">
<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.css" />
</head>
<body>
<div id="wrap">
<div id="head">
<h1>会員登録</h1>
</div>
<div id="content">
<p>記入した内容を確認して、「登録する」ボタンをクリックしてください</p>
<!-- Create HTML for screen after
registration -->
<form action=""
method="post">
<input
type="hidden" name="action" value="submit" />
<dl>
<dt>ニックネーム</dt>
<dd>
<?php
echo htmlspecialchars($_SESSION['join']['name'], ENT_QUOTES, 'UTF-8'); ?>
</dd>
<dt>パスワード</dt>
<dd>
【表示されません】
</dd>
<dt>写真など</dt>
<dd>
<img src="member_picture/<?php
echo $_SESSION['join']['image']; ?>" width="100"
height="100" alt="" />
</dd>
</dl>
<div><a
href="index.php?action=rewrite">« 書き直す</a> | <input
type="submit" value="登録する"
/></div>
</form>
</div>
</div>
</body>
</html>
------------------------
O6-14-3/join/thanks.php
-----------------------
<!DOCTYPE html>
<html lang="ja">
<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.css" />
</head>
<body>
<div id="wrap">
<div id="head">
<h1>会員登録</h1>
</div>
<div id="content">
<!-- Screen displayed when member
recording is completed -->
<p>ユーザー登録が完了しました</p>
<p><a href="../">ログインする</a></p>
</div>
</div>
</body>
</html>
------------------
O6-14-3/style.css//背景など
------------------
/*
Copyright (c) 2010, Yahoo! Inc. All rights
reserved.
Code licensed under the BSD License:
http://developer.yahoo.com/yui/license.html
version: 2.8.1
*/
body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,button,textarea,p,blockquote,th,td{margin:0;padding:0;}table{border-collapse:collapse;border-spacing:0;}fieldset,img{border:0;}address,caption,cite,code,dfn,em,strong,th,var,optgroup{font-style:inherit;font-weight:inherit;}del,ins{text-decoration:none;}li{list-style:none;}caption,th{text-align:left;}h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:normal;}q:before,q:after{content:'';}abbr,acronym{border:0;font-variant:normal;}sup{vertical-align:baseline;}sub{vertical-align:baseline;}legend{color:#000;}input,button,textarea,select,optgroup,option{font-family:inherit;font-size:inherit;font-style:inherit;font-weight:inherit;}input,button,textarea,select{*font-size:100%;}
/*
Copyright (c) 2010, Yahoo! Inc. All rights
reserved.
Code licensed under the BSD License:
http://developer.yahoo.com/yui/license.html
version: 2.8.1
*/
body{font:13px/1.231
arial,helvetica,clean,sans-serif;*font-size:small;*font:x-small;}select,input,button,textarea,button{font:99%
arial,helvetica,clean,sans-serif;}table{font-size:inherit;font:100%;}pre,code,kbd,samp,tt{font-family:monospace;*font-size:108%;line-height:100%;}
body {
background:
url(images/bg_main.png) top center repeat-y #eeeeee;
color:
#333;
}
#wrap {
width:
802px;
margin:
0 auto;
}
#head {
border-left:
1px solid #d4d4d4;
border-right:
1px solid #d4d4d4;
border-bottom:
1px solid #d4d4d4;
background:
url(images/bg_head.png) bottom left repeat-x #106eb7;
color:
#fff;
padding:
20px;
margin-bottom:
20px;
}
h1 {
background:
url(images/bg_ttl.png) top left no-repeat;
padding-left:
25px;
font-size:
197%;
font-weight:
bold;
}
h2 {
font-weight:
bold;
margin-bottom:
0.5em;
}
#content {
padding:
20px;
background:
url(images/bg_content.png) left bottom no-repeat #ecf7fc;
width:
720px;
min-height:
490px;
margin:
0 auto;
margin-bottom:
10px;
font-size:
153.9%;
}
* html #content {
height:
490px;
}
p {
line-height:
1.2em;
margin-bottom:
0.5em;
}
dl {
margin-bottom:
10px;
}
dt {
border-left:
5px solid #106eb7;
padding-left:
5px;
margin-bottom:
5px;
}
dd {
margin-bottom:
0.5em;
}
.required {
background-color:
#BB1850;
color:
#fff;
font-size:
90%;
padding:
2px;
margin-left:
10px;
}
#foot {
width:
780px;
text-align:
right;
}
th, td {
border:
1px solid #999;
padding:
3px;
}
th {
background-color:
#106eb7;
color:
#fff;
font-weight:
bold;
}
li {
list-style:
circle;
margin-left:
20px;
margin-bottom:
0.5em;
}
.paging {
margin-top:
10px;
text-align:
center;
}
.paging li {
display:
inline;
list-style:
none;
}
.error {
font-size:
90%;
color:
#BB1850;
}
#lead {
margin-bottom:
1em;
}
.msg {
clear:
both;
border-top:
1px solid #ccc;
padding:
10px 0;
}
.msg img {
float:
left;
margin-right:
5px;
}
.msg p {
margin:
0;
}
.msg .day,
.msg .day a {
font-size:
80%;
color:
#999;
}
-------------
/dbconnect.php
--------------
//Create a database connection program
<?php
try {
$db = new
PDO('mysql:dbname=mini_bbs;host=127.0.0.1;charset=utf8', 'root', 'root');
} catch (PDOException $e) {
echo 'DB接続エラー: ' . $e->getMessage();
}
?>
-----------------
O6-14-3/view.php
-----------------
<?php
session_start();
require('dbconnect.php');
if (empty($_REQUEST['id'])) {
header('Location:
index.php'); exit();
}
// 実際の投稿内容を表示する
$posts = $db->prepare('SELECT m.name,
m.picture, p.* FROM members m, posts p WHERE m.id=p.member_id AND p.id=? ORDER
BY p.created DESC');
$posts->execute(array($_REQUEST['id']));
?>
<!DOCTYPE html>
<html lang="ja">
<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.css" />
</head>
<body>
<div id="wrap">
<div id="head">
<h1>ひとこと掲示板</h1>
</div>
<div id="content">
<p>«<a href="index.php">一覧にもどる</a></p>
<?php
if ($post = $posts->fetch()):
?>
<div
class="msg">
<img
src="join/member_picture/<?php echo htmlspecialchars($post['picture'],
ENT_QUOTES, 'UTF-8'); ?>" width="48" height="48"
alt="<?php echo htmlspecialchars($post['name'], ENT_QUOTES, 'UTF-8');
?>" />
<p><?php echo
htmlspecialchars($post['message'], ENT_QUOTES, 'UTF-8'); ?><span
class="name">(<?php echo htmlspecialchars($post['name'], ENT_QUOTES, 'UTF-8');
?>)</span></p>
<p
class="day"><?php echo htmlspecialchars($post['created'],
ENT_QUOTES, 'UTF-8'); ?></p>
</div>
<?php
else:
?>
<p>その投稿は削除されたか、URLが間違えています</p>
<?php
endif;
?>
</div>
</div>
</body>
</html>
-----------------
O6-14-3/login.php//ログイン処理
-----------------
<?php
require('dbconnect.php');
session_start();
//ログイン情報を乗せるようにする
if ($_COOKIE['name'] != '') {
$_POST['name']
= $_COOKIE['name'];
$_POST['password']
= $_COOKIE['password'];
$_POST['save']
= 'on';
}
if (!empty($_POST)) {
//
ログインの処理
if
($_POST['name'] != '' && $_POST['password'] != '') {
$login = $db->prepare('SELECT
* FROM members WHERE name=? AND password=?');
$login->execute(array(
$_POST['name'],
sha1($_POST['password'])
));
$member =
$login->fetch();
if ($member) {
//
ログイン成功
$_SESSION['id']
= $member['id'];
$_SESSION['time']
= time();
//
ログイン情報を記録する
if
($_POST['save'] == 'on') {
setcookie('name',
$_POST['name'], time()+60*60*24*14);
setcookie('password',
$_POST['password'], time()+60*60*24*14);
}
header('Location:
index.php'); exit();
}
else {
$error['login']
= 'failed';
}
}
else {
$error['login']
= 'blank';
}
}
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD
XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html
xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta
http-equiv="Content-Type" content="text/html;
charset=UTF-8" />
<link rel="stylesheet"
type="text/css" href="style.css" />
<title>ログインする</title>
</head>
<body>
<div id="wrap">
<div id="head">
<h1>ログインする</h1>
</div>
<div id="content">
<div
id="lead">
<p>ネームとパスワードを記入してログインしてください。</p>
<p>入会手続きがまだの方はこちらからどうぞ。</p>
<p>»<a href="join/">入会手続きをする</a></p>
</div>
<form action=""
method="post">
<dl>
<dt>ネーム</dt>
<dd>
<input type="text" name="name"
size="35" maxlength="255" value="<?php echo
htmlspecialchars($_POST['name']); ?>" />
<?php if ($error['login'] == 'blank'): ?>
<p class="error">* ネームとパスワードをご記入ください</p>
<?php endif; ?>
<?php if ($error['login'] == 'failed'): ?>
<p class="error">* ログインに失敗しました。正しくご記入ください。</p>
<?php endif; ?>
</dd>
<dt>パスワード</dt>
<dd>
<input type="password" name="password"
size="35" maxlength="255" value="<?php echo
htmlspecialchars($_POST['password']); ?>" />
</dd>
<dt>ログイン情報の記録</dt>
<dd>
<input id="save" type="checkbox"
name="save" value="on">
<label for="save">次回からは自動的にログインする</label>
</dd>
</dl>member_picture
<div>
<input type="submit" value="ログインする" />
</div>
</form>
</div>
<div id="foot">
<p><img
src="images/txt_copyright.png" width="136"
height="15" alt="(C) H2O Space. MYCOM" /></p>
</div>
</div>
</body>
</html>
-------------------
O6-14-3/logout.php//ログアウト処理
-------------------
<?php
session_start();
// セッション情報を削除
$_SESSION = array();
if
(ini_get("session.use_cookies")) {
$params
= session_get_cookie_params();
setcookie(session_name(),
'', time() - 42000,
$params["path"],
$params["domain"],
$params["secure"],
$params["httponly"]
);
}
session_destroy();
// Cookie情報も削除
setcookie('name', '', time()-3600);
setcookie('password', '', time()-3600);
header('Location: login.php'); exit();
?>
------------------
O6-14-3/index.php//投稿画面を作る
-----------------
<?php
session_start();
require('dbconnect.php');
//ログイン状態であるかを検査する
if (isset($_SESSION['id']) &&
$_SESSION['time'] + 3600 > time()) {
//
ログインしている
$_SESSION['time']
= time();
$members
= $db->prepare('SELECT * FROM members WHERE id=?');
$members->execute(array($_SESSION['id']));
$member
= $members->fetch();
} else {
//
ログインしていない
header('Location:
login.php'); exit();
}
// データベースに投稿内容を記録する
if (!empty($_POST)) {
if
($_POST['message'] != '') {
$message
= $db->prepare('INSERT INTO posts SET member_id=?, message=?,
reply_post_id=?, created=NOW()');
$message->execute(array(
$member['id'],
$_POST['message'],
$_POST['reply_post_id']
));
header('Location:
index.php'); exit();
}
}
// 投稿を取得する
$page = $_REQUEST['page'];
if ($page == '') {
$page
= 1;
}
$page = max($page, 1);
// 最終ページを取得する
$counts = $db->query('SELECT COUNT(*) AS
cnt FROM posts');
$cnt = $counts->fetch();
$maxPage = ceil($cnt['cnt'] / 5);
$page = min($page, $maxPage);
$start = ($page - 1) * 5;
$start = max(0, $start);
$posts = $db->prepare('SELECT m.name,
m.picture, p.* FROM members m, posts p WHERE m.id=p.member_id ORDER BY
p.created DESC LIMIT ?, 5');
$posts->bindParam(1, $start,
PDO::PARAM_INT);
$posts->execute();
// 返信の場合
if (isset($_REQUEST['res'])) {
$response
= $db->prepare('SELECT m.name, m.picture, p.* FROM members m, posts p WHERE
m.id=p.member_id AND p.id=? ORDER BY p.created DESC');
$response->execute(array($_REQUEST['res']));
$table
= $response->fetch();
$message
= '@' . $table['name'] . ' ' . $table['message'];
}
// htmlspecialcharsのショートカット
function h($value) {
return
htmlspecialchars($value, ENT_QUOTES, 'UTF-8');
}
// 本文内のURLにリンクを設定します
function makeLink($value) {
return
mb_ereg_replace("(https?)(://[[:alnum:]\+\$\;\?\.%,!#~*/:@&=_-]+)",
'<a href="\1\2">\1\2</a>' , $value);
}
?>
<!DOCTYPE html>
<html lang="ja">
<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.css" />
</head>
<body>
<div id="wrap">
<div id="head">
<h1>ひとこと掲示板</h1>
</div>
<div id="content">
<div
style="text-align: right"><a href="logout.php">ログアウト</a></div>
<form action=""
method="post">
<dl>
<dt><?php echo h($member['name']); ?>さん、メッセージをどうぞ</dt>
<dd>
<textarea name="message" cols="50"
rows="5"><?php echo h($message); ?></textarea>
<input type="hidden" name="reply_post_id"
value="<?php echo h($_REQUEST['res']); ?>" />
</dd>
</dl>
//投稿内容を表示するためのHTMLを作る
<div>
<p>
<input type="submit" value="投稿する" />
</p>
</div>
</form>
<?php
foreach ($posts as $post):
?>
<div
class="msg">
<img
src="join/member_picture/<?php echo h($post['picture']); ?>"
width="48" height="48" alt="<?php echo
h($post['name']); ?>" />
<p><?php echo
makeLink(h($post['message'])); ?><span class="name">(<?php echo h($post['name']); ?>)</span>
[<a
href="index.php?res=<?php echo h($post['id']);
?>">Re</a>]</p>
<p
class="day"><a href="view.php?id=<?php echo
h($post['id']); ?>"><?php echo h($post['created']);
?></a>
<?php
if ($post['reply_post_id'] > 0):
?>
<a href="view.php?id=<?php echo
h($post['reply_post_id']); ?>">
返信元のメッセージ</a>
<?php
endif;
?>
<?php
if ($_SESSION['id'] == $post['member_id']):
?>
[<a href="delete.php?id=<?php
echo h($post['id']); ?>"
style="color: #F33;">削除</a>]
<?php
endif;
?>
</p>
</div>
<?php
endforeach;
?>
<ul class="paging">
<?php
if ($page > 1) {
?>
<li><a
href="index.php?page=<?php print($page - 1); ?>">前のページへ</a></li>
<?php
} else {
?>
<li>前のページへ</li>
<?php
}
?>
<?php
if ($page < $maxPage) {
?>
<li><a href="index.php?page=<?php
print($page + 1); ?>">次のページへ</a></li>
<?php
} else {
?>
<li>次のページへ</li>
<?php
}
?>
</ul>
</div>
</div>
</body>
</html>
-----------------------
O6-14-3/dbconnect.php //データベース接続のプログラム
-----------------------
<?php
try {
$db = new
PDO('mysql:dbname=mini_bbs;host=127.0.0.1;charset=utf8', 'root', 'root');
} catch (PDOException $e) {
echo 'DB接続エラー: ' . $e->getMessage();
}
?>
-------------------
O6-14-3/delete.php
------------------
<?php
session_start();
require('dbconnect.php');
if (isset($_SESSION['id'])) {
$id
= $_REQUEST['id'];
//
投稿を検査する
$messages
= $db->prepare('SELECT * FROM posts WHERE id=?');
$messages->execute(array($id));
$message
= $messages->fetch();
if
($message['member_id'] == $_SESSION['id']) {
//
削除する
$del
= $db->prepare('DELETE FROM posts WHERE id=?');
$del->execute(array($id));
}
}
header('Location: index.php'); exit();
?>
join