ブログに記事を書くときは、通常、説明のためにテキストの間に写真を表示する必要があります。 CKEditorはこれを実現するのに役立ちますが、プラグインを使用していない場合は、少し注意が必要な場合や操作が難しい場合があります。その理由は、CKEditorは投稿テキストに挿入される画像のURLのみを受け入れ、画像はローカルマシンではなく、インターネット上にすでに存在している必要があるためです。
ここで行う必要があるのは、投稿を書いている間に、プロジェクトの画像ディレクトリに画像をアップロードする方法を見つけることです。画像がアップロードされると、画像のURLが返送され、CKEditorで使用できるようになります。
まず、クリックするとユーザーのローカルコンピュータで画像を参照するボタンを追加します(要素をクリックするのと同じ方法で)。ユーザーが画像を選択すると、その画像はonChangeイベントでAjaxを使用して(ページをリロードせずに)バックグラウンドですぐにアップロードされ、その特定の画像のURLがサーバーから返されます。返されたURLはポップアップモーダルで表示され、ユーザーがクリックするとクリップボードにコピーされます。これで、ユーザーはCKEditorの画像アイコンをクリックして、画像のURLを貼り付けることができます。
これをミニプロジェクトに実装して、どのように機能するかを見てみましょう。
ckeditor-imagesというフォルダーを作成し、このフォルダー内に、imagesというサブフォルダーと、index.php、server.php、scripts.js、main.cssの4つのファイルを作成します。
画像フォルダには、CKEditorからアップロードされた画像が保存されます。
index.phpを開き、次のコードをその中に配置します。
index.php:
<?php include('server.php') ?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Uploading images in CKEditor using PHP</title>
<!-- Bootstra CSS -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" />
<!-- Custom styling -->
<link rel="stylesheet" href="main.css">
</head>
<body>
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2 post-div">
<!-- Display a list of posts from database -->
<?php foreach ($posts as $post): ?>
<div class="post">
<h3>
<a href="details.php?id=<?php echo $post['id'] ?>"><?php echo $post['title']; ?></a>
</h3>
<p>
<?php echo html_entity_decode(preg_replace('/\s+?(\S+)?$/', '', substr($post["body"], 0, 200))); ?>
</p>
</div>
<?php endforeach ?>
<!-- Form to create posts -->
<form action="index.php" method="post" enctype="multipart/form-data" class="post-form">
<h1 class="text-center">Add Blog Post</h1>
<div class="form-group">
<label for="title">Title</label>
<input type="text" name="title" class="form-control" >
</div>
<div class="form-group" style="position: relative;">
<label for="post">Body</label>
<!-- Upload image button -->
<a href="#" class="btn btn-xs btn-default pull-right upload-img-btn" data-toggle="modal" data-target="#myModal">upload image</a>
<!-- Input to browse your machine and select image to upload -->
<input type="file" id="image-input" style="display: none;">
<textarea name="body" id="body" class="form-control" cols="30" rows="5"></textarea>
</div>
<div class="form-group">
<button type="submit" name="save-post" class="btn btn-success pull-right">Save Post</button>
</div>
</form>
<!-- Pop-up Modal to display image URL -->
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title" id="myModalLabel">Click below to copy image url</h4>
</div>
<div class="modal-body">
<!-- returned image url will be displayed here -->
<input
type="text"
id="post_image_url"
onclick="return copyUrl()"
class="form-control"
>
<p id="feedback_msg" style="color: green; display: none;"><b>Image url copied to clipboard</b></p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- JQuery -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!-- Bootstrap JS -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
<!-- CKEditor -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/ckeditor/4.8.0/ckeditor.js"></script>
<!-- custom scripts -->
<script src="scripts.js"></script>
</body>
</html>
ご覧のとおり、CDNを介してブートストラップCSSとJSを追加しました。また、Ajax呼び出しを使用して画像をアップロードするため、JQueryも追加しました。最後に、フォームのテキストエリアでまだ初期化するCKEditorプラグインコードを追加しました。 scripts.jsは、JQueryスクリプトが存在する場所です。
投稿フォームの直後に、idがid="myModal"に設定されたポップアップモーダルのコードを追加しました。このモーダルは現在使用されていませんが、画像がアップロードされると、返された画像のURLがこのモーダルに表示されます。だから今は忘れてください。
http://localhost/ckeditor-images/index.phpにアクセスすると、静的な投稿とフォームが表示されます。 main.cssを開き、このページにいくつかのスタイルを追加しましょう。
main.css:
p {
font-size: 1.1em;
}
.post {
border: 1px solid #ccc;
padding: 10px;
margin-top: 15px;
}
.post h3 {
margin: 0px;
}
.post-div {
border: 1px solid #ccc;
margin-top: 30px;
margin-bottom: 30px;
padding: 20px;
}
.post-form {
margin-top: 80px;
}
/*DETAILS PAGE*/
.post-details p {
text-align: justify;
margin: 20px auto;
font-size: 1.2em;
}
.upload-img-btn {
position: absolute;
z-index: 9;
top: 35px;
right: 5px;
}
scripts.jsを開き、その中に次のコードを追加します:
scripts.js:
// initialize ckeditor
CKEDITOR.replace('body');
ページを更新すると、スタイルの変更と、CKEditorに多くのアイコンが読み込まれたテキストエリアが変更されていることがわかります。
ckeditor-imagesというデータベースを作成します。このデータベースで、フィールドを含むpostsというテーブルを作成します。
- id-INT(11)
- タイトル-VARCHAR(255)
- body-VARCHAR(255)
次に、1つ以上のダミーの投稿を投稿テーブルに挿入して、クエリを実行してページに表示できるようにします。
データベースへの接続
server.phpを開き、次のコードを入力します:
<?php
// connect to database
$db = mysqli_connect("localhost", "root", "", "ckeditor-images");
// retrieve posts from database
$result = mysqli_query($db, "SELECT * FROM posts");
$posts = mysqli_fetch_all($result, MYSQLI_ASSOC);
?>
このコードは、データベースにある投稿を$posts変数に取得します。この変数は、index.phpのコードの最初の行(index.php内のserver.phpファイルを含む行)のincludeステートメントによってindex.phpファイルで使用可能になります。
index.phpファイルで、属性class ="post"を持つdiv要素全体を削除し、次のコードに置き換えます。
// ... more code here
<?php if (isset($posts)): ?>
<?php foreach ($posts as $post): ?>
<div class="post">
<h3>
<a href="details.php?id=<?php echo $post['id'] ?>"><?php echo $post['title'] ?></a>
</h3>
<p><?php echo $post['body']; ?></p>
</div>
<?php endforeach ?>
<?php else: ?>
<h2>No posts available</h2>
<?php endif ?>
// ... more code here
ご覧のとおり、各投稿のタイトルをクリックすると、details.phpが投稿のIDを渡します。 details.phpという名前のファイルを作成し、その中にこのコードを貼り付けます:
details.php:
<?php
// connect to database
$db = mysqli_connect("localhost", "root", "", "ckeditor-images");
if (isset($_GET['id'])) {
$id = $_GET['id'];
$result = mysqli_query($db, "SELECT * FROM posts WHERE id=$id");
$post = mysqli_fetch_assoc($result);
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Uploading images in CKEditor using PHP</title>
<!-- Bootstra -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" />
<!-- Custom styling -->
<link rel="stylesheet" href="main.css">
</head>
<body>
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2 post-div">
<div class="post-details">
<h2><?php echo $post['title'] ?></h2>
<p><?php echo html_entity_decode($post['body']); ?></p>
</div>
</div>
</div>
</div>
<!-- JQuery -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!-- Bootstrap JS -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
<!-- JQuery scripts -->
<script>
</script>
</body>
</html>
上部のセクションで、データベースに接続し、index.phpページから送信された投稿IDを取得して、その特定の投稿にクエリを実行します。その後、投稿は$ post変数に保存され、ページに表示されます。
これで、CKEditorで実際に画像をアップロードするダイナミクスのコーディングを開始できます。 scripts.jsを開き、内部のすべてを次のように置き換えます:
scripts.js:
// initialize ckeditor
CKEDITOR.replace('body');
// Javascript function to copy image url to clipboard from modal
function copyUrl() {
var copyText = document.getElementById("post_image_url");
copyText.select();
document.execCommand("Copy");
// replace url with confirm message
$('#post_image_url').hide(1000);
$('#feedback_msg').show();
// hide modal after 2 seconds
setTimeout(function(){
$('#myModal').modal('hide');
$('#feedback_msg').hide();
$('#post_image_url').show();
}, 2000);
}
$(document).ready(function(){
// When user clicks the 'upload image' button
$('.upload-img-btn').on('click', function(){
// Add click event on the image upload input
// field when button is clicked
$('#image-input').click();
$(document).on('change', '#image-input', function(e){
// Get the selected image and all its properties
var image_file = document.getElementById('image-input').files[0];
// Initialize the image name
var image_name = image_file.name;
// determine the image extension and validate image
var image_extension = image_name.split('.').pop().toLowerCase();
if (jQuery.inArray(image_extension, ['gif', 'png', 'jpg', 'jpeg']) == -1) {
alert('That image type is not supported');
return;
}
// Get the image size. Validate size
var image_size = image_file.size;
if (image_size > 3000000) {
alert('The image size is too big');
return;
}
// Compile form values from the form to send to the server
// In this case, we are taking the image file which
// has key 'post_image' and value 'image_file'
var form_data = new FormData();
form_data.append('post_image', image_file);
form_data.append('uploading_file', 1);
// upload image to the server in an ajax call (without reloading the page)
$.ajax({
url: 'index.php',
method: 'POST',
data: form_data,
contentType: false,
cache: false,
processData: false,
beforeSend : function(){
},
success : function(data){
// how the pop up modal
$('#myModal').modal('show');
// the server returns a URL of the uploaded image
// show the URL on the popup modal
$('#post_image_url').val(data);
}
});
});
});
});
このコードのコメントに従ってください。そうすれば、手順を理解できます。まず、ユーザーは「画像のアップロード」ボタンをクリックします。これにより、表示がnoneに設定されているファイル入力に対してクリックイベントがトリガーされます。ユーザーがローカルコンピューターから画像を選択すると、ファイル入力でonChangeイベントがトリガーされます。ここで、Ajaxを使用して画像をアップロードします。
この時点で、画像はすでにAjaxリクエストでサーバーに送信されています。しかし、これまでのところserver.phpでは、データベースに接続しているだけです。 Ajaxリクエストから画像を受け取り、それを画像フォルダーにアップロードするためのコードはまだ作成されていません。今それをしましょう。
server.phpファイルをもう一度開き、次のコードを追加します。
server.php:
// ... more code here ...
// if 'upload image' buttton is clicked
if (isset($_POST['uploading_file'])) {
// Get image name
$image = $_FILES['post_image']['name'];
// image file directory
$target = "images/" . basename($image);
if (move_uploaded_file($_FILES['post_image']['tmp_name'], $target)) {
echo "http://localhost/ckeditor-images/" . $target;
exit();
}else{
echo "Failed to upload image";
exit();
}
}
このコードは、画像に付属するAjaxリクエストを受け入れ、画像を画像フォルダーにアップロードし、完全修飾URLを画像に返します。この時点では、ユーザーはまだ投稿作成フォームに投稿を書くのに忙しく、これはすべてバックグラウンドで行われていることに注意してください。
サーバーから返されたURLは、ユーザーがURLをコピーするためにポップアップするポップアップモーダルに表示されます。モーダルがポップアップし、ユーザーが表示されたURLをクリックすると、クリップボードにコピーされ、ユーザーはこのURLを適切な場所に貼り付けることで、CKEditorでこの画像URLの使用に進むことができます。
このチュートリアルのコアコンセプトはほぼ完成しています。今残っているのは、投稿をサーバーに送信してデータベースに保存するために送信を押すことです。そのために、1つのファイルにのみ触れます。
server.phpを開き、ファイルの最後に次のコードを追加します:
// ... more code here ...
// if form save button is clicked, save post in the database
if (isset($_POST['save-post'])) {
$title = mysqli_real_escape_string($db, $_POST['title']);
$body = htmlentities(mysqli_real_escape_string($db, $_POST['body']));
$sql = "INSERT INTO posts (title, body) VALUES ('$title', '$body')";
mysqli_query($db, $sql);
header("location: index.php");
}
これで、このチュートリアルは終了です。このチュートリアルでの私たちの目的と、私たちがどのようにそれに取り組んだかをよく理解していただければ幸いです。
詳細h2>
この時点で、すべてが正常に機能しているようです。画像をアップロードし、CKEditorでそのURLを使用していますが、このシステムはどれほど効率的ですか。投稿を書き始め、いくつかの画像をアップロードした後、疲れを感じているとしましょう。アップロードを元に戻すにはどうすればよいですか。サーバーのスペースをどのように解放しますか?私が提案する解決策は、postIDと画像の名前のみを取得する画像テーブルをデータベースに作成することです。画像をアップロードするたびに、postIDとしてnullを使用して画像テーブルに画像名を保存します。気が変わって投稿を最後に保存しないと、画像テーブルにnullが残ります。次に、関連するpostIDとしてnullを持つすべてのデータベースイメージをクエリするスクリプトを記述できます。これに挑戦し、コーディングしてください。問題が発生した場合は、下のコメントに残してください。ヘルプが表示されます。
いつものように、お時間をいただきありがとうございます。これがお役に立てば幸いです。この投稿を楽しんだら、他のチュートリアルをチェックして、私のサイトを友達と共有して推薦してください。
よろしく!