Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Hochladen von Bildern in CKEditor ohne Verwendung eines Plugins

Wenn Sie einen Artikel in Ihrem Blog schreiben, müssen Sie oft Bilder zwischen Texten anzeigen, normalerweise zu Illustrationszwecken. CKEditor hilft Ihnen dabei, aber es kann ein bisschen schwierig oder schwierig sein, damit zu arbeiten, wenn Sie kein Plugin verwenden. Der Grund dafür ist, dass CKEditor nur die URL des Bildes akzeptiert, die in den Beitragstext eingefügt werden soll, und das Bild bereits im Internet und nicht auf Ihrem lokalen Computer vorhanden sein muss.

Was wir jetzt tun müssen, ist, einen Weg zu finden, das Bild in ein Bildverzeichnis in unserem Projekt hochzuladen, während wir noch den Beitrag schreiben. Sobald das Bild hochgeladen wurde, wird die URL des Bildes zurückgesendet, die wir dann in unserem CKEditor verwenden können.

Als Erstes fügen wir eine Schaltfläche hinzu, die, wenn sie angeklickt wird, den lokalen Computer des Nutzers nach Bildern durchsucht (genauso wie ein Klick auf ein -Element). Sobald der Nutzer ein Bild auswählt, wird dieses Bild sofort im Hintergrund mit Ajax (ohne Neuladen der Seite) in einem onChange-Ereignis hochgeladen und die URL dieses bestimmten Bildes wird vom Server zurückgegeben. Die zurückgegebene URL wird in einem Popup-Modal angezeigt, das in die Zwischenablage kopiert wird, wenn der Benutzer darauf klickt. Der Benutzer kann nun auf das Bildsymbol im CKEditor klicken und die URL des Bildes darin einfügen.

Lassen Sie uns dies in einem Miniprojekt implementieren und sehen, wie es funktioniert.

Erstellen Sie einen Ordner namens ckeditor-images und erstellen Sie in diesem Ordner einen Unterordner namens images und 4 Dateien, nämlich:index.php, server.php, scripts.js und main.css.

Der Bilderordner enthält die Bilder, die von unserem CKEditor hochgeladen wurden.

Öffnen Sie index.php und platzieren Sie den folgenden Code darin.

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">&times;</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>

Wie Sie sehen können, haben wir Bootstrap CSS und JS über CDN hinzugefügt. Wir haben auch JQuery hinzugefügt, weil wir die Bilder mit Ajax-Aufrufen hochladen werden. Zuletzt haben wir den CKEditor-Plugin-Code hinzugefügt, den wir noch in unserem Textbereich im Formular initialisieren müssen. scripts.js ist der Ort, an dem sich das JQuery-Skript befindet.

Unmittelbar nach dem Post-Formular haben wir Code für das Popup-Modal hinzugefügt, wobei die ID auf id="myModal" gesetzt ist. Dieses Modal wird derzeit nicht verwendet, aber wenn das Bild hochgeladen wurde, wird die zurückgegebene URL des Bildes in diesem Modal angezeigt. Also vergiss es jetzt.

Wenn Sie zu http://localhost/ckeditor-images/index.php gehen, sehen Sie den angezeigten statischen Beitrag und das Formular. Öffnen Sie main.css und fügen Sie dieser Seite ein paar Stile hinzu.

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;
}

Öffnen Sie scripts.js und fügen Sie diesen Code darin ein:

scripts.js:

// initialize ckeditor
CKEDITOR.replace('body');

Aktualisieren Sie die Seite und Sie werden einige Änderungen im Design sowie im Textbereich bemerken, der jetzt unser CKEditor ist, der mit vielen Symbolen geladen ist.

Erstellen Sie eine Datenbank namens ckeditor-images. Erstellen Sie in dieser Datenbank eine Tabelle namens posts mit Feldern:

  • id - INT(11)
  • Titel - VARCHAR(255)
  • body - VARCHAR(255)

Fügen Sie nun einen oder mehrere Dummy-Posts in die Posts-Tabelle ein, damit wir sie abfragen und auf der Seite anzeigen können.

Verbindung zur Datenbank herstellen

Öffnen Sie server.php und geben Sie diesen Code ein:

<?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);
?>

Dieser Code ruft die Beiträge aus der Datenbank in eine $posts-Variable ab. Diese Variable wird in unserer index.php-Datei durch die include-Anweisung in der ersten Codezeile in index.php verfügbar gemacht – der Zeile, die die server.php-Datei in index.php einschließt.

Entfernen Sie in der Datei index.php das gesamte div-Element mit dem Attribut class="post" und ersetzen Sie es durch diesen Code:

// ... 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

Wie Sie sehen können, führt jeder Beitrag, wenn auf seinen Titel geklickt wird, zur details.php, die die ID des Beitrags an ihn weitergibt. Erstellen Sie eine Datei namens details.php und fügen Sie diesen Code darin ein:

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>

Im oberen Abschnitt stellen wir eine Verbindung zur Datenbank her, holen uns die Post-ID, die von der index.php-Seite gesendet wurde, und fragen diesen bestimmten Post ab. Der Beitrag wird dann in der Variable $post gespeichert, die dann auf der Seite angezeigt wird.

Jetzt können wir mit der Codierung der Dynamik des tatsächlichen Hochladens des Bildes im CKEditor beginnen. Öffnen Sie scripts.js und ersetzen Sie alles darin:

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);
				}
			});
		});

	});
});

Folgen Sie den Kommentaren in diesem Code und Sie werden die Schritte verstehen. Zunächst klickt der Nutzer auf die Schaltfläche „Bild hochladen“. Dies löst ein Click-Ereignis bei der Dateieingabe aus, deren Anzeige auf „Keine“ gesetzt wurde. Sobald der Benutzer ein Bild von seinem lokalen Computer auswählt, wird ein onChange-Ereignis bei der Dateieingabe ausgelöst, und hier laden wir das Bild mit Ajax hoch.

Zu diesem Zeitpunkt wird unser Bild bereits in einer Ajax-Anfrage an den Server gesendet. Aber bisher haben wir uns in unserer server.php nur mit der Datenbank verbunden. Wir haben den Code noch nicht geschrieben, um das Bild von der Ajax-Anforderung zu erhalten und es in den Bilderordner hochzuladen. Lass uns das jetzt tun.

Öffnen Sie die Datei server.php noch einmal und fügen Sie diesen Code hinzu:

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();
  	}
}

Dieser Code akzeptiert die mit dem Bild gelieferte Ajax-Anforderung, lädt das Bild in den Bilderordner hoch und gibt eine vollständig qualifizierte URL an das Bild zurück. Denken Sie daran, dass der Nutzer zu diesem Zeitpunkt noch damit beschäftigt ist, seinen Beitrag im Beitragserstellungsformular zu schreiben, und all dies im Hintergrund geschieht.

Die vom Server zurückgegebene URL wird dann in einem Pop-up-Modal angezeigt, das dem Nutzer angezeigt wird, um die URL zu kopieren. Wenn das Modal erscheint und der Benutzer auf die angezeigte URL klickt, wird sie in die Zwischenablage kopiert und der Benutzer kann diese Bild-URL in CKEditor verwenden, indem er diese URL an der entsprechenden Stelle einfügt.

Wir sind mit dem Kernkonzept dieses Tutorials ziemlich fertig. Jetzt müssen wir nur noch auf Senden klicken, damit unser Beitrag an den Server gesendet und in der Datenbank gespeichert wird. Dazu berühren wir nur eine Datei.

Öffnen Sie server.php und fügen Sie diesen Code am Ende der Datei hinzu:

// ... 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");
}

Und das bringt uns zum Ende dieses Tutorials. Ich hoffe, Sie haben unser Ziel in diesem Tutorial gut verstanden und wie wir es angegangen sind.

 Ein genauerer Blick

An diesem Punkt scheint alles gut zu funktionieren. Wir laden ein Bild hoch und verwenden seine URL in unserem CKEditor ganz gut, aber wie effizient ist dieses System. Angenommen, Sie beginnen mit dem Schreiben eines Beitrags und fühlen sich dabei erschöpft, nachdem Sie ein paar Bilder hochgeladen haben. Wie können Sie die Uploads rückgängig machen? Wie geben Sie Speicherplatz auf Ihrem Server frei? Eine Lösung, die ich vorschlagen würde, ist, dass Sie eine Bildtabelle in der Datenbank erstellen, die nur die PostID und den Namen des Bildes enthält. Jedes Mal, wenn Sie ein Bild hochladen, speichern Sie den Bildnamen in der Bildertabelle mit null als postID. Wenn Sie Ihre Meinung ändern und den Beitrag am Ende nicht speichern, bleibt die Null in der Bildertabelle. Dann können Sie ein Skript schreiben, das alle Datenbankbilder abfragt, die null als zugehörige postIDs haben. Fordern Sie sich damit heraus und codieren Sie es. Wenn Sie auf Schwierigkeiten stoßen, hinterlassen Sie es in den Kommentaren unten und Hilfe wird kommen.

Wie immer danke für deine Zeit. Ich hoffe, Sie finden das hilfreich. Wenn Ihnen dieser Beitrag gefallen hat, dann schauen Sie sich bitte meine anderen Tutorials an und teilen und empfehlen Sie meine Seite mit Ihren Freunden.

Viele Grüße!