Upload plików na serwer - problem z funkcją getimagesize

0

Witam!

mam problem przy upload-zie
otóż chciałem zrobić upload plików na swojej stronie i wszystko chodzi jednakże chciałem zrobić zabezpieczenie dot. wczytywania dużych obrazków czyli np większych niż 640x460 w sieci wyszukałem informację jak to zrobić ale mój skrypt nie działa
oto mój kod w części gdzie chcę pobrać wielkość pliku

if (isset($_FILES['plik']['type'])) 
										{
											if(($_FILES['plik']['type']=='image/jpeg')or$_FILES['plik']['type']=='image/gif')
												{
													przeskalujObrazek($_FILES['plik']['name'],80,80);
													
													move_uploaded_file($patch.$_FILES['plik']['tmp_name'].'/'.$_FILES['plik']['name'],
													$_SERVER['DOCUMENT_ROOT'].'/test/upload/'.$_FILES['plik']['name']);
													echo 'Odebrano plik. Początkowa nazwa: '.$_FILES['plik']['name'];
												}
											else
												{
													echo 'Błędny typ pliku. Dopuszczalne tylko pliki JPG i GIF';
												} 

a oto procedura która ma zmieniać wielkość pliku który jest za duży

function przeskalujObrazek($obrazek, $max_szerokosc, $max_wysokosc) {

  $rozmiar = GetImagesSize($obrazek);
  $szerokosc = $rozmiar[0];
  $wysokosc = $rozmiar[1];

  $wspolczynnik_x = $max_szerokosc / $szerokosc;
  $wspolczynnik_y = $max_wysokosc / $wysokosc;

  if (($szerokosc <= $max_szerokosc) && ($wysokosc <= $max_wysokosc)) {
    $nowa_szerokosc = $szerokosc;
    $nowa_wysokosc = $wysokosc;
  }
  else if (($wspolczynik_x * $wysokosc) < $max_wysokosc) {
    $nowa_wysokosc = ceil($wspolczynnik_x * $wysokosc);
    $nowa_szerokosc = $max_szerokosc;
  }
  else {
    $nowa_szerokosc = ceil(wspolczynnik_y * $szerokosc);
    $nowa_wysokosc = $max_wysokosc;
  }

  $zrd = ImageCreateFromJpeg($obrazek);
  $prz = ImageCreate($nowa_szerokosc, $nowa_wysokosc);
  ImageCopyResized($prz, $zrd, 0, 0, 0, 0, $nowa_szerokosc, $nowa_wysokosc, $szerokosc, $wysokosc);

  header('Content-type: Image/jpeg');
  ImageJpeg($prz, null, -1);
  ImageDestroy($prz);
  ImageDestroy($zrd);
} 

po odpaleniu stronki i próbie uploadu pliku otrzymuję komunikat
Fatal error: Call to undefined function getimagessize() i ścieżka do pliku

sprawdziłem, że biblioteki GD są dostępne na serwerze bo doczytałem, ze taki komunikat z reguły pojawia się gdy ich nie ma

ktoś poratuje w potrzebie :) ?

0

nie moze znalezc metody GetImagesSize(), bo moze takowej nie ma jak to wszystko co pokazales, ew. nie am dostepu. gdzie masz funkcje: GetImagesSize ?

0

bo funkcja getimagessize a getimagesize to dwie różne funkcje..

bosh, z literówkami w nazwie funkcji przychodzić na forum..
przecież nawet w google jak wyszukasz błąd to Ci pokaże literówkę....

user image

ps. następnym razem używaj znaczników ``` z nazwą języka, czyli np. o tak tu kod php`



edit: ** TWÓJ KOD JEST DZIURAWY **, można nim wgrać plik php na serwer.
nigdy nie sprawdzaj typu pliku po MIME TYPE!
0

rzeczywiście jest błąd w nazwie sorki dzisiaj sprawdzę czy działa

0

po zastosowaniu polecenia

$rozmiar = GetImageSize($_FILES['plik']['name']);

otrzymuję taki komunikat

Warning: getimagesize(20c1204a-f4b8-448a-a2e6-9e68dc402284_5.jpg) [function.getimagesize]: failed to open stream: No such file or directory in [tutaj ścieżka do pliku] on line 130

i nic, proszę o poradę

0

A manuala czytał? $_FILES['plik']['name'] to nazwa pliku jaką dał Ci uzytkownik! czytaj z $_FILES['userfile']['tmp_name']

a tak na serio - czytaj z http://php.net/manual/pl/features.file-upload.post-method.php

I uwaga: poświęć chwilę myslenia i zabezpiecz ten kod, bo masz dziurę jak cholera. Tak jak mówi @dzek69 spokojnie tym można wgrać plik php na serwer, odpalić go i zrobić jesień średniowiecza na nim.

0

OK poświęciłem trochę czasu i manuala przeczytałem a w nim jest kawałek kodu

$uploaddir = './';
$uploadfile = $uploaddir . basename($_FILES['userfile']['name']);

echo '<pre>';
if (move_uploaded_file($_FILES['userfile']['tmp_name'], $uploadfile)) {
    echo "File is valid, and was successfully uploaded.\n";
} else {
    echo "Possible file upload attack!\n";
}

i wszystko działa OK jeśli chodzi o przesyłanie samego pliku.
W dalszym ciągu nie kumam dwóch tematów:

  1. o co chodzi z tym sprawdzaniem typu pliku po MIME TYPE ? i gdzie jest dziura w kodzie ?
  2. jak przy uploadzie pliku, jeśli jest za duży, zmniejszyć jego rozmiar. W manualu znalazłem opis i część kodu:
// File and new size
$filename='test.jpg';
$percent = 0.5;

// Content type
header('Content-Type: image/jpeg');

// Get new sizes
list($width, $height) = getimagesize($filename);
$newwidth = $width * $percent;
$newheight = $height * $percent;

// Load
$thumb = imagecreatetruecolor($newwidth, $newheight);
$source = imagecreatefromjpeg($filename);

// Resize
imagecopyresized($thumb, $source, 0, 0, 0, 0, $newwidth, $newheight, $width, $height);

// Output
imagejpeg($thumb);

ale w dalszym ciągu nie umiem połączyć obu części w prawidłowy sposób.
Jak to wszystko połączyłe wyszedł mi komunikat

test11.jpg
Warning: Cannot modify header information - headers already sent by (output started at /[ścieżka]/index.php:9) in /[ścieżka]/addaddb.php on line 108

a później jakieś cyrki typu

����JFIF��>CREATOR: gd-jpeg v1.0 (using IJG JPEG v62), default quality ��C $.' ",#(7),01444'9=82<.342��C 2!!22222222222222222222222222222222222222222222222222����"�� ���}!1AQa"q2���#B��R��$3br� %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz��������������������������������������������������������������������������� ���w!1AQaq"2�B���� #3R�br�
itd

proszę o pomoc

zmniejszenie indentacji w kodzie oraz dodanie znaczników <code> - furious programming

0

Próbujesz być za szybki. NIE KOPIUJ KODU. Sklejając losowe kawałki znalezione w sieci NIGDY Ci nic nie wyjdzie. Nie tak się programuje!

Jeżeli znalazłeś jakiś kawałek kodu - MUSISZ zrozumieć każdą jego linijkę, co robi, zanim tego użyjesz.

Co robi header? Nie wiesz - migiem do manuala! Nie zrozumiesz? Pomóż sobie wikipedią i opisem protokołu HTTP.
Co robi list? Nie wiesz - czytaj manual. NIE PRZECHODŹ DO KOLEJNEJ LINIJKI jeżeli nie zrozumiesz poprzedniej.

Mała podpowiedź co do MIME - jak wczytasz się w specyfikację protokołu HTTP, to dowiesz się, że pliki przesyłane do serwera w ten sposób posiadają informacje o MIME type OD KLIENTA. Czyli to ja wysyłam Tobie jakiś plik i to JA decyduję, co jest wpisane w MIME type. A więc ja mogę Ci wysłać plik skasujwszystko.php nadając mu MIME type image/jpeg. I Twój kod to łyknie.

Co do przeskalowania obrazków - to nie będzie takie łatwe. Kod skopiowany przez Ciebie jest mocno prymitywny - na chama zeskaluje Ci obrazki, nie zachowując proporcji. Oprócz dokładnej znajomości funkcji imagecopyresized będziesz potrzebował też trochę matematyki.

0

co do MIME to można było się domyśleć o co chodzi, ale dzięki za wyjaśnienie. Nie podpowiedziałeś natomiast nawet gdzie szukać odpowiedzi na pytanie: jak teraz to zmienić i od czego zacząć ?
jeśli chodzi o skalowalność obrazka w moim kodzie to akurat jest zachowana bo szerokość i wysokość jest przemnażana przez 0.5.

ok posiedzę zobaczę

0

@dzek69 dobrze Ci mówi. Posiedź, zobacz. błąd masz w tym że dajesz coś na wyjście przed ustawieniem headera. te krzaczki na wyjściu sa ok (to plik jpeg). z mime do sprawdzania poprawności obrazka osobiście stosuje exif_imagetype.

0

odgrzewam trochę temat. miałem chwilową przerwę ale musiałem wrócić do tego uplodu plików na serwer i myślałem, że już wszystko będzie OK ale zgrywają mi się źle przeskalowane pliki a nie umiem wychwycić błędu.

kod

$remote_file = "img/imgad/".$id.$rozszerzenie;
imagejpeg($image_source,$remote_file,100); 
chmod($remote_file,0644);
list($image_width, $image_height) = getimagesize($remote_file);

if($image_width>$max_upload_width || $image_height >$max_upload_height)
{
	$proportions = $image_width/$image_height;

	if($image_width>$image_height)
	{
		$new_width = $max_upload_width;
		$new_height = round($max_upload_width/$proportions);
	}		
	else
	{
		$new_height = $max_upload_height;
		$new_width = round($max_upload_height*$proportions);
	}		

	$new_image = imagecreatetruecolor($new_width , $new_height);
	list($imgwidth, $imgheight) = getimagesize($remote_file);
	$image_source = imagecreatefromjpeg($remote_file);

	imagecopyresampled($new_image, $image_source, 0, 0, 0, 0, $new_width, $new_height, $image_width, $image_height);
	imagejpeg($new_image,$remote_file,100);
				
	imagedestroy($new_image);
}

$new_image = imagecreatetruecolor($new_width , $new_height);
$image_source = imagecreatefromjpeg($remote_file);
		
imagecopyresampled($new_image, $image_source, 0, 0, 0, 0, $new_width, $new_height, $image_width, $image_height);
imagejpeg($new_image,$remote_file,100);

imagedestroy($new_image);

sprawdzałem 4 przypadki

  1. plik oryginalny jest większy niż docelowy
  2. plik oryginalny jest mniejszy niż docelowy
  3. wysokość w oryginalnym jest mniejsza niż w docelowym
  4. szerokość w oryginale jest mniejsza niż w docelowym

wyniki:
1.
c27ce7e863.png

  1. wywaliło mi błędy

785cdac27d.png
4.
b2f85edee9.png

nie wiem dlaczego oryginalny plik nie jest skalowany do rozmiarów docelowych tylko robi się mniejszy i wkleja do nowo utworzonego (z czarnym tłem, dlatego takie czarne pole)

dodanie znacznika <code class="php"> - @furious programming

1

Jak ktoś wcześniej zwrócił uwagę próbujesz pisać sklejając znalezione kawałki kodu nie zastanawiając się nad sensem tego co kod właściwie robi. Jeżeli pierwszy warunek if nie zostanie spełniony zmienne $new_height i $new_width nie zostaną zainicjowane więc jak chcesz na podstawie ich wartości tworzyć obrazek? Ponad to w przypadku gdy obraz jest większy od maksymalnego tworzysz nowy dwa razy. Po co?

0

OK znalazłem miejsce gdzie zmienne $new_width i $new_height nie były inicjowane w sytuacji kiedy obrazek był mniejszy od docelowego ale dlaczego tworzę podwójnie plik ? a nawet jeśli to dlaczego prawdziwy obrazek stanowi jedynie wycinek "płótna" ?

`dodanie znaczników ``` - @furious programming

0

OK znalazłem ten drugi błąd z podwójnym zapisywaniem pliku dzięki

1 użytkowników online, w tym zalogowanych: 0, gości: 1