font-awesomeのハンバーガー

document.getElementByIdで、アイコンがクリックされた際に、document.body.className = ‘menu-open’とdocument.body.className = ”を返します。なお、font-awesomeはCDNで取得します。

https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Top Menu Tab</title>
	<meta name="viewport" content="width=device-width, initial-scale=1">
	<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
	<style>
		body {
			padding: 0;
			margin: 0;
			font-family: Verdana, sans-serif;
			background: #eee;
			color: #333;
			padding: 8px;
			box-sizing: border-box;
			width: 100%;
			height: 100%;
			overflow-x: hidden;
		}
		#cover {
			background: #000;
			opacity: 0.6;
			width: 100%;
			height: 100%;
			position: absolute;
			top: 0;
			left:0;
			z-index:1;
			display: none;

		}
		#menu {
			z-index:2;
			position: absolute;
			top: 0;
			right: -180px;
			color: #fff;
			background: #4c81e9;
			padding: 8px;
			box-sizing: border-box;
			width: 180px;
			min-height: 100%;
			transition: .4s;
		}

		#show, #hide {
			float: right;
			cursor: pointer;
		}
		body.menu-open {
			overflow-y: hidden;

		}
		body.menu-open #cover {
			display: block;

		}
		body.menu-open #menu {
			right: 0;
			
		}
	</style>
</head>
<body>

	<i class="fa fa-bars" id="show"></i>
		<h1>Hello</h1>
		<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Itaque eveniet eius repudiandae aut, dolorum amet beatae distinctio quam, nemo minus, velit quod assumenda. Magnam distinctio fugiat in expedita officiis vitae.</p>
		<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Itaque eveniet eius repudiandae aut, dolorum amet beatae distinctio quam, nemo minus, velit quod assumenda. Magnam distinctio fugiat in expedita officiis vitae.</p>
		<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Itaque eveniet eius repudiandae aut, dolorum amet beatae distinctio quam, nemo minus, velit quod assumenda. Magnam distinctio fugiat in expedita officiis vitae.</p>
	<div id="cover"></div>

	<div id="menu">
		<i class="fa fa-times" id="hide"></i>
		<ul>
			<li>Menu</li>
			<li>Menu</li>
			<li>Menu</li>
			<li>Menu</li>
			<li>Menu</li>
		</ul>
	</div>
	<script>
	(function(){
		'use strict';

		var show = document.getElementById('show');
		var hide = document.getElementById('hide');

		show.addEventListener('click', function(){
			document.body.className = 'menu-open'
		});

		hide.addEventListener('click', function(){
			document.body.className = ''
		});
	})();
	</script>
</body>
</html>

ハンバーガーメニュー

addEventListener:The EventTarget.addEventListener() method registers the specified listener on the EventTarget it’s called on. The event target may be an Element in a document, the Document itself, a Window, or any other object that supports events (such as XMLHttpRequest).

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Top Menu Tab</title>
	<meta name="viewport" content="width=device-width, initial-scale=1">
	<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
	<style>
		body {
			padding: 0;
			margin: 0;
			font-family: Verdana, sans-serif;
		}
		#menu {
			position: absolute;
			top: 0;
			right: 0;
			color: #fff;
			background: #4c81e9;
			box-sizing: border-box;
			width: 180px;
			min-height: 100%;
		}
		#main {
			z-index: 1;
			background: #eee;
			position: absolute;
			top: 0;
			left: 0;
			color: #333;
			padding: 8px;
			box-sizing: border-box;
			width: 100%;
			height: 100%;
			overflow: auto;
			transition: .4s;
		}
		#main.menu-open {
			left: -180px;
		}
		#show {
			float: right;
			cursor: pointer;
		}
	</style>
</head>
<body>
	<div id="menu">
		<ul>
			<li>Menu</li>
			<li>Menu</li>
			<li>Menu</li>
			<li>Menu</li>
			<li>Menu</li>
		</ul>
	</div>
	<div id="main">
		<i class="fa fa-bars" id="show"></i>
		<h1>Hello</h1>
		<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Itaque eveniet eius repudiandae aut, dolorum amet beatae distinctio quam, nemo minus, velit quod assumenda. Magnam distinctio fugiat in expedita officiis vitae.</p>
		<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Itaque eveniet eius repudiandae aut, dolorum amet beatae distinctio quam, nemo minus, velit quod assumenda. Magnam distinctio fugiat in expedita officiis vitae.</p>
		<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Itaque eveniet eius repudiandae aut, dolorum amet beatae distinctio quam, nemo minus, velit quod assumenda. Magnam distinctio fugiat in expedita officiis vitae.</p>
	</div>
	<script>
	(function(){
		'use strict';

		var show = document.getElementById('show');
		var main = document.getElementById('main');

		show.addEventListener('click', function(){
			if (main.className === 'menu-open'){
				main.className = '';
			} else {
				main.className = 'menu-open';
			}
		});
	})();
	</script>
</body>
</html>

クリッカブルタブメニュー

%e7%84%a1%e9%a1%8c

event.preventDefault()
If this method is called, the default action of the event will not be triggered.

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Top Menu Tab</title>
	<style>
		body {
			padding:0;
			margin:0;
			font-family: Verdana, sans-serif;
		}
		.container {
			padding: 0;
			margin: 30px auto;
			width: 500px;
			background: #dce0e0;
		}
		ul.menu {
			list-style: none;
			padding: 0;
			margin: 0;
			font-size: 0;
		}
		ul.menu li {
			display: inline-block;
		}
		ul.menu li a {
			display: inline-block;
			font-size: 14px;
			width: 80px;
			height: 20px;
			line-height: 20px;
			text-align: center;
			text-decoration: none;
			padding: 7px;
			color: #333;
		}
		ul.menu li a.active {
			background: #353d3e;
			color: #fff;
		}
		ul.menu li a:not(.active):hover {
			opacity: 0.5;
			transition: .8s;
		}
		.content {
			font-size: 14px;
			padding: 7px 10px;
			line-height: 1.4;
			background: #353d3e;
			color: #fff;
			min-height: 150px;
			display: none;
		}
		.content.active {
			display: block;
		}
	</style>
</head>
<body>
<div class="container">
	<ul class="menu">
		<li><a href="#" data-id="about" class="active  menu_item">About</a></li>
		<li><a href="#" data-id="service" class="menu_item">Service</a></li>
		<li><a href="#" data-id="contact" class="menu_item">Contact</a></li>
	</ul>
	<div class="content active" id="about">
	Lorem1 ipsum dolor sit amet, consectetur adipisicing elit. Ad, beatae eos ab, esse cupiditate doloribus cumque tenetur atque aspernatur, maxime ipsam nemo ipsum quis placeat. Facere ipsam debitis possimus nostrum!
	</div>
	<div class="content" id="service">
	Lorem2 ipsum dolor sit amet, consectetur adipisicing elit. Ad, beatae eos ab, esse cupiditate doloribus cumque tenetur atque aspernatur, maxime ipsam nemo ipsum quis placeat. Facere ipsam debitis possimus nostrum!
	</div>
	<div class="content" id="contact">
	Lorem3 ipsum dolor sit amet, consectetur adipisicing elit. Ad, beatae eos ab, esse cupiditate doloribus cumque tenetur atque aspernatur, maxime ipsam nemo ipsum quis placeat. Facere ipsam debitis possimus nostrum!
	</div>
<p></p>
<script>
	(function(){
		'use strict'

		var menuItems = document.getElementsByClassName('menu_item');
		var contents = document.getElementsByClassName('content');

		var i;

		for (i=0; i < menuItems.length; i++){
			menuItems&#91;i&#93;.addEventListener('click', function(e){
				e.preventDefault();

				var i;
				for (i=0; i < menuItems.length; i++){
					menuItems&#91;i&#93;.className = 'menu_item';
				}
				this.className = 'menu_item active';

				var i;
				for (i=0; i < contents.length; i++){
					contents&#91;i&#93;.className = 'content';
				}
				document.getElementById(this.dataset.id).className = 'content active';

			});
		}

	})();
</script>
</body>
</html>

functions, config

%e7%84%a1%e9%a1%8c

<?php

function connectDb(){
  try {
    return new PDO(DSN, DB_USER, DB_PASSWORD);
  } catch (PDOException $e){
    echo $e->getMessage();
    exit;
  }
}

function h($s){
  return htmlspecialchars($s, ENT_QUOTES, "UTF-8");
}

function setToken(){
  if (!isset($_SESSION['token'])){
    $_SESSION['token'] = sha1(uniqid(mt_rand(), true));
  }
}

function checkToken(){
  if (empty($_POST['token']) || $_POST['token'] != $_SESSION['token']){
    echo "不正な処理です!";
    exit;
  }
}
/*

create database contact_php;
grant all on contact_php.* to dbuser@localhost identified by 'xxxx';

use contact_php

create table entries (
  id int not null auto_increment primary key,
  name varchar(255),
  email varchar(255),
  memo text,
  created datetime,
  modified datetime
);

alter table entries add status enum('active', 'deleted') default 'active' after memo;
*/

define('DSN','mysql:host=localhost;dbname=contact_php');
define('DB_USER','dbuser');
define('DB_PASSWORD','xxxx');

define('SITE_URL','http://192.168.33.10:8000');
define('ADMIN_URL', SITE_URL.'/admin/');

error_reporting(E_ALL & ~E_NOTICE);
session_set_cookie_params(0, '');

edit, delete

<?php

require_once('../config.php');
require_once('../functions.php');

session_start();
$dbh = connectDb();

if (preg_match('/^&#91;1-9&#93;&#91;0-9&#93;*$/', $_GET&#91;'id'&#93;)){
    $id = (int)$_GET&#91;'id'&#93;;
} else{
    echo "不正なIDです!";
    exit;
}

if ($_SERVER&#91;'REQUEST_METHOD'&#93; != "POST"){
  setToken();

  $stmt = $dbh->prepare("select * from entries where id = :id limit 1");
  $stmt->execute(array(":id" => $id));
  $entry = $stmt->fetch() or die("no one found!");
  $name = $entry['name'];
  $email = $entry['email'];
  $memo = $entry['memo'];

} else {
  checkToken();

  $name = $_POST['name'];
  $email = $_POST['email'];
  $memo = $_POST['memo'];

  $error = array();

  if(!filter_var($email, FILTER_VALIDATE_EMAIL)){
    $error['email'] = 'メールアドレスの形式が正しくありません';
  }
  if($email == ''){
    $error['email'] = 'メールアドレスを入力してください';
  }
  if($memo == ''){
    $error['memo'] = '内容を入力してください';
  }
  if(empty($error)){

    $sql = "update entries set
            name = :name,
            email = :email,
            memo = :memo,
            modified = now()
            where id = :id";
     $stmt = $dbh->prepare($sql);
     $params = array(
       ":name" => $name,
       ":email" => $email,
       ":memo" => $memo,
       ":id" => $id
     );
     $stmt->execute($params);

    header('Location: '.ADMIN_URL);
    exit;
  }
}

?>
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="utf-8">
  <title>データの編集</title>
</head>
<body>
  <h1>データの編集</h1>
  <form method="POST" action="">
    <p>お名前:<input type="text" name="name" value="<?php echo h($name); ?>"></p>
    <p>メールアドレス*:<input type="text" name="email" value="<?php echo h($email); ?>">
    <?php if($error&#91;'email'&#93;){ echo h($error&#91;'email'&#93;); } ?></p>
    <p>内容*:</p>
    <p><textarea name="memo" cols="40" rows="5"><?php echo h($memo); ?></textarea>
    <?php if($error&#91;'memo'&#93;){ echo h($error&#91;'memo'&#93;); } ?></p>
    <p><input type="submit" value="更新"></p>
    <input type="hidden" name="token" value="<?php echo h($_SESSION&#91;'token'&#93;); ?>">
  </form>
  <p><a href="<?php echo ADMIN_URL; ?>">戻る</a>
</body>
</html>

delete

<?php

require_once('../config.php');
require_once('../functions.php');

$dbh = connectDb();

$id = (int)$_POST&#91;'id'&#93;;

$dbh->query("update entries set status = 'deleted' where id = $id");

echo $id;

thanks

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="utf-8">
  <title>ありがとうございました!</title>
</head>
<body>
  <h1>ありがとうございました!</h1>
  <p></p>
  <p><a href="index.php">お問い合わせフォームに戻る</a></p>
</body>
</html>

問い合わせ管理システム

index.php

<?php

require_once('config.php');
require_once('functions.php');

session_start();
if ($_SERVER&#91;'REQUEST_METHOD'&#93; != "POST"){
  setToken();
} else {
  checkToken();

  $name = $_POST&#91;'name'&#93;;
  $email = $_POST&#91;'email'&#93;;
  $memo = $_POST&#91;'memo'&#93;;

  $error = array();

  if(!filter_var($email, FILTER_VALIDATE_EMAIL)){
    $error&#91;'email'&#93; = 'メールアドレスの形式が正しくありません';
  }
  if($email == ''){
    $error&#91;'email'&#93; = 'メールアドレスを入力してください';
  }
  if($memo == ''){
    $error&#91;'memo'&#93; = '内容を入力してください';
  }
  if(empty($error)){
    $dbh = connectDb();

    $sql = "insert into entries
            (name, email, memo, created, modified)
            values
            (:name, :email, :memo, now(), now())";
    $stmt = $dbh->prepare($sql);
    $params = array(
      ":name" => $name,
      ":email" => $email,
      ":memo" => $memo
    );
    $stmt->execute($params);

    header('Location: '.SITE_URL.'/thanks.html');
    exit;
  }
}

?>
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="utf-8">
  <title></title>
</head>
<body>
  <h1>お問い合わせフォーム</h1>
  <form method="POST" action="">
    <p>お名前:<input type="text" name="name" value="<?php echo h($name); ?>"></p>
    <p>メールアドレス*:<input type="text" name="email" value="<?php echo h($email); ?>">
    <?php if($error&#91;'email'&#93;){ echo h($error&#91;'email'&#93;); } ?></p>
    <p>内容*:</p>
    <p><textarea name="memo" cols="40" rows="5"><?php echo h($memo); ?></textarea>
    <?php if($error&#91;'memo'&#93;){ echo h($error&#91;'memo'&#93;); } ?></p>
    <p><input type="submit" value="送信"></p>
    <input type="hidden" name="token" value="<?php echo h($_SESSION&#91;'token'&#93;); ?>">
  </form>
  <p><a href="<?php echo ADMIN_URL; ?>">管理者ページ</a>
</body>
</html>

contact

<?php

require_once('../config.php');
require_once('../functions.php');

$dbh = connectDb();

$entries = array();

$sql = "select * from entries where status = 'active' order by created desc";

foreach($dbh->query($sql) as $row){
  array_push($entries, $row);
}

// var_dump($entries);
// exits;

?>
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="utf-8">
  <title>お問い合わせ一覧</title>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
</head>
<body>
  <h1>一覧データ</h1>
  <p><span id="num"><?php echo count($entries); ?></span>件あります。</p>
  <ul>
    <?php foreach($entries as $entry): ?>
      <li id="entry_<?php echo h($entry&#91;'id'&#93;); ?>"><?php echo h($entry&#91;'email'&#93;); ?>
        <a href="edit.php?id=<?php echo h($entry&#91;'id'&#93;); ?>">[編集]</a>
        <span class="deleteLink" data-id="<?php echo h($entry&#91;'id'&#93;); ?>">[削除]</span>
      </li>
    <?php endforeach; ?>
  </ul>
  <style>
  .deleteLink{
    color: blue;
    cursor: pointer;
  }
  </style>
  <p><a href="<?php echo SITE_URL; ?>">お問い合わせフォームに戻る</a></p>
  <script>
  $(function(){
    $('.deleteLink').click(function(){
      if (confirm("削除してもよろしいですか?")){
        var num = $('#num').text();
        num--;
        $.post('./delete.php', {
           id: $(this).data('id')
          }, function(rs){
            $('#entry_' + rs).fadeOut(800);
            $('#num').text(num);
          });
      }
      });
    });
  </script>
</body>
</html>

Basic認証の作り方

コマンドラインから、htpasswd -c .htpass loginnameと打ちます。

[vagrant@localhost admin]$ htpasswd -c .htpasswd password
New password:
Re-type new password:
Adding password for user password
[vagrant@localhost admin]$ ls -la
合計 12
drwxr-xr-x. 2 vagrant vagrant 4096 11月 15 00:33 2016 .
drwxrwxr-x. 3 vagrant vagrant 4096 11月 15 00:31 2016 ..
-rw-rw-r--. 1 vagrant vagrant   23 11月 15 00:33 2016 .htpasswd

続いて、.htaccessを作ります。

[vagrant@localhost admin]$ vi .htaccess
AuthType Basic
AuthName "Enter your ID & Password"
AuthUserFile /home/vagrant/contact/admin/.htpasswd
require valid-user
[vagrant@localhost admin]$ ls -la
合計 16
drwxr-xr-x. 2 vagrant vagrant 4096 11月 15 00:39 2016 .
drwxrwxr-x. 3 vagrant vagrant 4096 11月 15 00:31 2016 ..
-rw-rw-r--. 1 vagrant vagrant  122 11月 15 00:39 2016 .htaccess
-rw-rw-r--. 1 vagrant vagrant   23 11月 15 00:33 2016 .htpasswd

Mysql, config.php, functions.phpの設定

[vagrant@localhost ~]mysql -u root
create database contact_php;
grant all on contact_php.* to dbuser@localhost identified by 'hogehoge';

use contact_php

create table entries (
  id int not null auto_increment primary key,
  name varchar(255),
  email varchar(255),
  memo text,
  created datetime,
  modified datetime
);
[vagrant@localhost ~]$ mysql -u dbuser -p contact_php

config.php

<?php

define('DSN','mysql:host=localhost;dbname=contact_php');
define('DB_USER','dbuser');
define('DB_PASSWORD','hogehoge');

define('SITE_URL','http://192.168.33.10:8000/');
define('ADMIN_URL', SITE_URL.'admin/');

error_reporting(E_ALL & ~E_NOTICE);
session_set_cookie_params(0, '/contacts_php');
&#91;/php&#93;

function.php
&#91;php&#93;
<?php

function connectDb(){
  try {
    return new PDO(DSN, DB_USER, DB_PASSWORD);
  } catch (PDOException $e){
    echo $e->getMessage();
    exit;
  }
}

function h($s){
  return htmlspecialchars($s, ENT_QUOTES, "UTF-8");
}

Carbon インスタンス

// $dt = new Carbon();
// $dt = Carbon::now();
// $dt = new Carbon('2016-12-20 11:32:23');
//$dt = new Carbon('tomorrow');
//$dt = Carbon::today();
//$dt = Carbon::tommorow();
// $dt = Carbon::yesterday();
// $dt = Carbon::parse('2016-12-12 11:32:32');
// $dt = Carbon::create(2020,12, 12, 11, 32, 32);
$dt = Carbon::createFromFormat('Y/m/d H', '2016/12/20 20');

日時情報の取得

$dt = Carbon::now();
//echo $dt->year . PHP_EOL;
//echo $dt->month . PHP_EOL;
//echo $dt->day . PHP_EOL;
//echo $dt->hour . PHP_EOL;
//echo $dt->minute . PHP_EOL;
//echo $dt->second . PHP_EOL;
//echo $dt->dayOfWeek . PHP_EOL;
//echo $dt->dayOfYear . PHP_EOL;
//echo $dt->weekOfMonth . PHP_EOL;
//echo $dt->weekOfYear . PHP_EOL;
// echo $dt->timestamp . PHP_EOL;
// echo $dt->tzName . PHP_EOL;
echo $dt->format('Y年m月d日') . PHP_EOL;

日付判定

//var_dump($dt->isToday()) . PHP_EOL;
//var_dump($dt->isTommorow()) . PHP_EOL;
//var_dump($dt->isYesterday()) . PHP_EOL;
//var_dump($dt->isFuture()) . PHP_EOL;
//var_dump($dt->isPast()) . PHP_EOL;
//var_dump($dt->isLeapYear()) . PHP_EOL;
//var_dump($dt->isWeekday()) . PHP_EOL;
//var_dump($dt->isWeekend()) . PHP_EOL;
//var_dump($dt->isSameDay(Carbon::now())) . PHP_EOL;

変数をとって、日時を比較

$dt1 = Carbon::create(2020, 10, 1);
$dt2 = Carbon::create(2020, 11, 1);

// var_dump($dt1->eq($dt2)) . PHP_EOL;
//var_dump($dt1->gt($dt2)) . PHP_EOL;
//var_dump($dt1->lt($dt2)) . PHP_EOL;
//var_dump(Carbon::create(2010, 10, 10)->between($dt1, $dt2)) . PHP_EOL;
//echo $dt1->max($dt2) . PHP_EOL;
//echo $dt1->min($dt2) . PHP_EOL;

日付計算

// echo $dt->addYear(). PHP_EOL;
//echo $dt->addYears(3). PHP_EOL;
//echo $dt->subYears(3). PHP_EOL;
//echo $dt->addWeekdays(3). PHP_EOL;
//echo $dt->addWeekdays(3)->addWeekHours(3)->addWeekMinutes(3). PHP_EOL;

コピーメソッド

$dt = Carbon::now();
echo $dt->copy()->addYear() . PHP_EOL;
echo $dt . PHP_EOL;

日時指定

//echo $dt->startOfDay() . PHP_EOL;
//echo $dt->endOfDay() . PHP_EOL;
//echo $dt->startOfMonth() . PHP_EOL;
//echo $dt->endOfMonth() . PHP_EOL;
//echo $dt->startOfWeek() . PHP_EOL;
//echo $dt->endOfWeek() . PHP_EOL;
//echo $dt->next(Carbon::MONDAY) . PHP_EOL;
//echo $dt->previous(Carbon::MONDAY) . PHP_EOL;
//echo $dt->firstOfMonth(Carbon::MONDAY) . PHP_EOL;
//echo $dt->lastOfMonth(Carbon::MONDAY) . PHP_EOL;
//echo $dt->nthOfMonth(3, Carbon::MONDAY) . PHP_EOL;

日時の差

$dt1 = Carbon::create(2020, 10, 1);
$dt2 = Carbon::create(2020, 11, 1);

//echo $dt1->diffInDays($dt2) . PHP_EOL;
//echo $dt1->diffInHours($dt2) . PHP_EOL;
//echo $dt1->diffInMinutes($dt2) . PHP_EOL;
//echo $dt1->diffForHumans($dt2) . PHP_EOL;

setTestNow()を使った判定

$dt = Carbon::now();
$birthday = Carbon::create(1990, 10, 1);
Carbon::setTestNow(Carbon::create(2020, 10, 1));
echo Carbon::now() . PHP_EOL;
if($birthday->isBirthday(Carbon::now())){
  echo ':)' . PHP_EOL;
} else {
  echo ':<' . PHP_EOL;