Mensen,

Wat wil ik: voor een website wil ik bestanden kunnen uploaden naar een server. Vervolgens wil ik dat er een link naar die bestanden in een database komt te staan. (Want volgens mij kan je geen bestanden opslaan in een database.) Als laatste wil ik dan op een andere pagina, als men ingelogd is kan men dan bij die pagina, de inhoud van de map "uploads" kan opvragen.

Concreet is de vraag is er een actuele tutorial die mij daarbij kan helpen?


Ik heb zelf deze gevonden: http://www.codingcage.com/2014/12/file-upload-and-view-with-php-and-mysql.html
En deze maar die is zonder database Daar zit overigens wel een mooi mededelingenschema in: http://phphulp.jorendewit.nl/view/12/

De vraag bij de scripts uit de link en degene die hier op het forum staan is: zijn ze, vanwege de leeftijd, nog actueel en veilig te gebruiken.

Als iemand mij zou willen helpen heel graag. (en nee, ik verwacht echt niet dat jullie nu een compleet script gaan zitten typen.)
Bestanden sla je graag op op een filesystem, en niet in een database. Dat laatste kan wel in een BLOB-veld, maar is in mijn ogen behoorlijk foutgevoelig en niet efficiënt en het maakt je database er ook niet kleiner op, wat extra langere tijd voor backups maken duurt.

Als je op bestandstype en mime-type controleert, dan ben je erg veilig.
Als je het wiel niet nogmaals wilt uitvinden kan je ook de Upload-class van verot.net gebruiken.
Overigens het deel van inloggen waar ik over spreek dat heb ik al het gaat mij echt om het uploaden van de files en het werken met de database daaraan.
In de database sla je de relatieve verwijzing op. Dus als je user_rob_4314124.jpg opslaat op je filesystem. Dan sla je in de database ook de tekst user_rob_4314124.jpg op. Zo kan je er koppelingen mee doen, zoals de UserID van de eigenaren, of tags om uploads te zoeken in je beheerpaneel.
@Rubensky waarvoor wil je het gaan gebruiken? Hoe groot zijn de bestanden? Hoeveel gebruikers heb je? Is een NAS, opslag in de cloud (een of andere filesharing-dienst, bijvoorbeeld, ik noem maar wat, Dropbox) of een private FTP server (hangt ook van bestandsgrootte) geen beter alternatief?
Zo doe ik het. Is voor een recepten website.

Plaatje + begeleidend tekst bestand opladen.

Plaatje + text worden in de db opgeslagen en als bestanden.

Werkt prima.

<script>

function setTitle ($this) {
	$this = $this.substr(0,$this.lastIndexOf('.'));
	$this = $this.replace(/"/g,' ');
	$this = $this.replace(/'/g,' ');
	$this = $this.replace(/,/g,' ');
	$this = $this.replace(/\?/g,' ');
	$this = $this.replace(/\!/g,' ');
	$this = $this.replace(/\@/g,' ');
	$this = $this.replace(/-/g,' ');
	$this = $this.replace(/--/g,'-');
	$this = $this.replace(/_/g,' ');
	$this = $this.replace(/   /g,' ');
	$this = $this.replace(/  /g,' ');
	$this = $this.replace('C:\\fakepath\\','');
//	$this = $this.replace('.jpg','');
//	$this = $this.replace('.gif','');
//	$this = $this.replace('.png','');
	document.getElementById('whatsit').value = $this;
	document.getElementById('whatsit').select();
}

function setRecipe ($this) {
	if ( $this.length ) {
		document.getElementById('recipe').checked = true;
	}
}
</script>

<h2>Latest uploaded image</h2>

<div id="showPict">

	<div id="nav">
		<div id="navL"><?php echo $isFirst; ?></div>
		<div id="navR"><?php echo $isLast; ?></div>
	</div>

	<div class="divClear"></div>

	<div id="divL" class="container">

		<figure style="max-width: 260px;">
			<a href="/store/?pid=<?php echo $pid . "&isLast=true"; ?>" title="Click to show details" style="border: none;">
				<img id="latestImage" src="?gim=1" />
			</a>
			<figcaption>
				<a href="/store/?pid=<?php echo $pid . "&isLast=true"; ?>" title="Click to show details"><?php echo ( $pid > 0 ? $pid  . " - " : "" ) . $title; ?></a>
			</figcaption>
		</figure>

		<h3>Please upload a new picture and title</h3>

		<div id="errmsg"><h4><?php echo $errmsg; ?></h4></div>

		<form enctype="multipart/form-data" method="POST">

			<p><input type="hidden" name="MAX_FILE_SIZE" value="<?php echo $maxFileSize; ?>">

			<p>Choose an image (<?php echo $maxFileSizekB; ?>): <input id="imagefile" type="file" name="imagefile" required onchange="setTitle(this.value);"></p>

			<p>Enter a title for that image : <input id="whatsit" name="whatsit" size="40"></p>

			<p>Choose a recipefile : <input id="recipetxt" type="file" name="recipetxt" onchange="setRecipe(this.value);"></p>

			<p>Is this for a recipe? <input id="recipe" type="checkbox" name="recipe" value="1"></p>

			<p><input type="submit" name="submit" value="Upload image"></p>

		</form>

	</div>
	
	<div class="divClear"></div>

	<?php include_once( _INIT_PATH . "counter.php"); ?>

	<div id="foot"><?php include_once( _INIT_PATH . "footer.php" ); ?></div>

</div>


Het upload script :

<?php

// http://www.wellho.net/solutions/php-example-php-form-image-upload-store-in-mysql-database-retreive.html
// http://www.wellho.net/resources/ex.php4?item=h113/pic_alog.php
// http://stackoverflow.com/questions/10892286/images-not-displaying-from-database-and-file

$errmsg = "";
$maxFileSize = "150000";
$maxFileSizekB = "max. 150kB";
$latest_image = "latest_image.img";
$latest_recipe = "latest_recipe.img";

include_once( $_SERVER["DOCUMENT_ROOT"] . "/init/" . "connect.php");

if ( $_REQUEST["submit"] ) {

//	echo $_FILES["imagefile"]["name"] . "<br />";
//	echo $_FILES["imagefile"]["size"];
//	exit();

	if ( ( $_FILES["imagefile"]["size"] > 0 ) && ( $_FILES["imagefile"]["name"] <> "" ) && ( $_REQUEST["whatsit"] <> "" ) ) {

		$extensions = array("pict", "gif", "jpg", "png", "txt");
		$imageFileType = strtolower( pathinfo( $_FILES["imagefile"]["name"],PATHINFO_EXTENSION ) );
		if ( $imageFileType == "jpeg" ) {
			$imageFileType = "jpg";
		}

/*
echo $imageFileType;
echo "<pre>";
print_r ($extensions);
echo "</pre>";
$os = ( in_array( $imageFileType , $extensions, TRUE ) == TRUE );
echo  $os;
exit();
*/

		if( in_array( $imageFileType , $extensions ) == TRUE ) {

			move_uploaded_file( $_FILES["imagefile"]["tmp_name"], $latest_image );
			// latest.img is container to temp store bytes image

			$recipeUploaded = FALSE;
			if ( $_FILES["recipetxt"]["name"] <> "" ) {
					move_uploaded_file( $_FILES["recipetxt"]["tmp_name"], $latest_recipe );
					// recipe.img is container to temp store bytes of text
					$recipeUploaded = TRUE;
			} 

//			see http://www.w3schools.com/php/php_file_upload.asp
//			$imageFileType = pathinfo( $target_file,PATHINFO_EXTENSION );

//			see http://www.phpeasystep.com/phptu/25.html for img size and type

			list( $width, $height, $type, $attr ) = getimagesize( $latest_image );
			$size = filesize( $latest_image );

			$mime = getimagesize( $latest_image );
			$imgMime = $mime['mime'];

			$instr = fopen( $latest_image, "rb") ;

			if ( count($instr) < $maxFileSize ) {
				$image = addslashes( fread( $instr, filesize( $latest_image ) ) ); // 
				$instrStore = fopen( $latest_image, "rb") ;
				$imageStore = fread( $instrStore, filesize( $latest_image ) );
				if ( $recipeUploaded == TRUE ) {
					$instrtxt = fopen( $latest_recipe, "rb" );
					$recipeText = addslashes( fread( $instrtxt, filesize( $latest_recipe ) ) );
				} else {
					$recipeText = "";
				}

				$uniqid = uniqid();
				$uniqidPath1 = substr( $uniqid, 0 , 4) . "/";
				$uniqidPath2 = substr( $uniqid , 4, 4) . "/";
				$imgurl = $uniqidPath1 . $uniqidPath2 ;
				$recipeText = filter_var( $recipeText, FILTER_SANITIZE_SPECIAL_CHARS );
				$title = filter_var( $_REQUEST["whatsit"], FILTER_SANITIZE_SPECIAL_CHARS );

				$imgType = $extensions[$type];
				$imgWidth = $width;
				$imgHeight = $height;
				$imgSize = $size;
				$isRecipe = filter_var( $_REQUEST["recipe"], FILTER_SANITIZE_SPECIAL_CHARS );
				$hasTextfile = ( $recipeText <> "" );

			// START MAKING THUMB
			// insert code for making thumb
			/*** create a second variable for the thumbnail ***/

			$size = getimagesize( $latest_image );
			/*** get the aspect ratio (height / width) ***/
			$aspectRatio = (float)($size[0] / $size[1]);

			/*** the height of the thumbnail ***/
			$thumb_height = 100;

			/*** the thumb width is the thumb height/aspectratio ***/
			$thumb_width = $thumb_height * $aspectRatio;

			/***  get the image source ***/
			$functions = array(
				IMAGETYPE_GIF => 'imagecreatefromgif',
				IMAGETYPE_JPEG => 'imagecreatefromjpeg',
				IMAGETYPE_PNG => 'imagecreatefrompng',
			);

			//$src = ImageCreateFromjpeg($latest_image);
			$src = $functions[$size[2]]($latest_image);

			/*** create the destination image ***/
			$destImage = ImageCreateTrueColor($thumb_width, $thumb_height);
			imagealphablending( $destImage, false );
			imagesavealpha( $destImage, true );

			/*** copy and resize the src image to the dest image ***/
			ImageCopyResampled($destImage, $src, 0,0,0,0, $thumb_width, $thumb_height, $width, $height);

			/*** start output buffering ***/
			ob_start();

			/***  export the image ***/
			$functions2 = array(
				IMAGETYPE_GIF => 'imagegif',
				IMAGETYPE_JPEG => 'imagejpeg',
				IMAGETYPE_PNG => 'imagepng',
			);

			//imageJPEG($destImage);
			$functions2[$size[2]]($destImage);

			/*** stick the image content in a variable ***/
			$image_thumb = addslashes(ob_get_contents());

			/*** clean up a little ***/
			ob_end_clean();

			// END MAKING THUMB

			// BEGIN SAVE THE $recipeText AND $imageStore AS FILES,
			// BESIDES OR INSTEAD OF ALSO SAVING IN DATABASE
				$recipePix = $_SERVER['DOCUMENT_ROOT'] . _RECIPEPATH;
				$structure = $recipePix . $uniqidPath1 . $uniqidPath2 ;

				if ( !is_dir( $structure ) ) {
					if ( !mkdir( $structure, 0777, TRUE ) ) {
						// if dir exist, simply ignore this warning
						echo "Directory exists";
					}
				}

				$sanatized = str_ireplace ( " " , "-" , html_entity_decode( $title ) ) ;
				$sanatized = str_ireplace ( "\"" , "_" ,   $sanatized ) ;
				$sanatized = str_ireplace ( "'" , "_" ,  $sanatized ) ;
				$sanatized = str_ireplace ( "__" , "_" , $sanatized ) ;

				if ( $recipeText <> "" ) {
					if ( !file_put_contents( $structure . $sanatized . "." . "txt", html_entity_decode( $recipeText ) ) ) {
						$errmsg = "Saving of textfile has failed";
					}
				}

				//chown($structure . $uniqid.txt, 'http'); // this does not work on my NAS
				if ( !file_put_contents( $structure . $sanatized . "." . $imgType, $imageStore ) ) {
					$errmsg = "Saving of imagefile has failed";
				}
			// END SAVE IMAGE AND RECIPETXT AS FILES

			// IF YOU DO NOT WANT TO SAVE THE IMAGE IN THE DATABASE,
			// SKIP THE 'imgdata' FIELD AND '$image' VAR
			// YOU MAY ALSO WANT TO SKIP THE FILESIZE CHECK

				$theDate = date("Y-m-d H:i:s");
				$db->query("INSERT INTO " .  _PIX . " (title, titlesanatized, imgdata, imgurl, uniqueid, width, height, type, mime, size, thumb_data, thumb_width, thumb_height, date, recipe, has_textfile, recipetxt ) values ('" . 
				$title . "','" .
				$sanatized . "','" .
				$image . "','" .
				$imgurl . "','" .
				$uniqid . "','" .
				$imgWidth . "','" .
				$imgHeight . "','" .
				$imgType . "','" .
				$imgMime . "','" .
				$imgSize . "','" .
				$image_thumb . "','" .
				$thumb_width . "','" .
				$thumb_height . "','" .
				$theDate . "','" .
				$isRecipe . "','" .
				$hasTextfile . "','" .
				$recipeText . "')");
				$numm = mysqli_affected_rows($db);
				$errmsg = 'Image' . ($numm > 0 ? ' ' : ' not ') . 'added to Database' ;
			} else {
				$errmsg = "Image is too large!";
			}
		} else {
			$errmsg = "This is not an image";
		}
	} else {
		if ( ( $_FILES["imagefile"]["name"] <> "" ) && ( $_FILES["imagefile"]["size"] == 0 ) ) {
			$errmsg = "Image is too large";
		} else {
			$errmsg = "No image selected";
		}
	}
}
// Find out about latest image

$gotten = $db->query("SELECT * FROM " .  _PIX . " ORDER BY pid DESC LIMIT 1");
if ( $row = $gotten->fetch_object() ) {
	$pid = $row->pid;
	$title = $row->title;
	$bytes = $row->imgdata;
} else {
	$errmsg = "No images in the database";
	$title = "No database image available";
	// Put up a picture of our training centre
	$instr = fopen( _ROOT . "/images/WorldMap.png","rb" );
	$bytes = fread( $instr, filesize( _ROOT . "images/WorldMap.png" ) );
}

// If this is the image request, send out the image

if ($_REQUEST[gim] == 1) {
	header("Content-type: image/jpeg");
	print $bytes;
	exit ();
}
include_once( _INIT_PATH . "navigation.php");

$_REQUEST["isFirst"] = "true";
$_REQUEST["isLast"] = "true";

setNavigation();

?>

Alleen de rechten op 777 zetten is erg overdreven ;-).
Dank voor dit mooie script. Nog even paar vragen Upload jij de bestanden daadwerkelijk naar de database?

2 waar is de connectie met de database?

Wat ik wil is de bestanden in een aparte map op mijn server en alleen een link naar het bestand opslaan in mijn database.

(anders wordt de database zo extreem groot.)

Ten aanzien van de andere vraag die mij gesteld ik gebruik nu ruimte bij een hosting provider.
Alleen metagegevens slaat hij op in de database. Zoals bestandsnaam, URL, een uniek ID, Mimetypes, grootes.
2 waar is de connectie met de database?


Regel 13

Alleen metagegevens slaat hij op in de database. Zoals bestandsnaam, URL, een uniek ID, Mimetypes, grootes.


Nee hoor, niet alleen de meta gegevens worden opgeslagen, ook de afbeelding zelf.

Bij regel 171-173 staat duidelik wat te doen als je de afbeelding NIET wilt opslaan in de databse.
Dank voor de uitleg.

Dan ga ik maar eens aan de slag met ik denk dit gedeelte:


   $theDate = date("Y-m-d H:i:s");
                $db->query("INSERT INTO " .  _PIX . " (title, titlesanatized, imgdata, imgurl, uniqueid, width, height, type, mime, size, thumb_data, thumb_width, thumb_height, date, recipe, has_textfile, recipetxt ) values ('" . 
                $title . "','" .
                $sanatized . "','" .
                $image . "','" .
                $imgurl . "','" .
                $uniqid . "','" .
                $imgWidth . "','" .
                $imgHeight . "','" .
                $imgType . "','" .
                $imgMime . "','" .
                $imgSize . "','" .
                $image_thumb . "','" .
                $thumb_width . "','" .
                $thumb_height . "','" .
                $theDate . "','" .
                $isRecipe . "','" .
                $hasTextfile . "','" .
                $recipeText . "')");
                $numm = mysqli_affected_rows($db);
                $errmsg = 'Image' . ($numm > 0 ? ' ' : ' not ') . 'added to Database' ;
            } else {
                $errmsg = "Image is too large!";
            }
        } else {
            $errmsg = "This is not an image";
        }
    } else {
        if ( ( $_FILES["imagefile"]["name"] <> "" ) && ( $_FILES["imagefile"]["size"] == 0 ) ) {
            $errmsg = "Image is too large";
        } else {
            $errmsg = "No image selected";


Want in principe wil ik alleen pdf txt en docx bestanden opslaan in een map. En de gegevens daarvan in de database. (niet de bestanden zelf.)

Als ik dat goed begrijp dan kan ik ook nog eens gaan kijken maar dat ligt nog een paar kilometer voor me hoor en daar gaat het me nu echt niet om de bestanden verschillend opslaan en filteren.

Reageren