PHP: Problem mit Images

Fragen zu allen anderen Programmiersprachen.
Benutzeravatar
redacid
Beiträge: 581
Registriert: 29.08.2004 17:06

PHP: Problem mit Images

Beitrag von redacid »

Hallo allerseits,

da ich mir einen beruflichen Aufstieg erhoffe, wenn ich PHP/SQL lerne (ich könnte evtl. in eine andere Abteilung der Firma wechseln), versuche ich gerade, mir ein paar wichtige Grundlagen anzueignen.

Mein erstes "Projekt" war ein Besucherzähler :mrgreen: . Lacht nicht! Das war schon schwierig genug, da ich von PHP und SQL bislang noch überhaupt keine Ahnung hatte und mir selbst für die paar Zeilen, die für einen Zähler nötig sind, alles zusammensuchen musste. Nun bin ich soweit, dass der Zähler in der MySQL-Datenbank samt IP gespeichert wird und er wird als grafischer Zähler angezeigt.

Dieser grafische Zähler wird durch 10 verschiedene Grafiken zusammengesetzt (jede Ziffer von 0-9 eine Grafik). Das sieht auch erstmal gut aus, aber ich hätte den Zähler lieber intern auf ein Image gerendert und dann dieses angezeigt, so dass nur noch eine Grafik angezeigt wird.

Ich hatte es also versucht mit imagecreate/imagecopy/imagejpeg.

Hier mal nur ein ganz kurzer Test, der einfach eine Grafik kopieren soll:

Code: Alles auswählen

<html>
<head>
<title>Image</title>
</head>

<body>
<?php

$bild="counter.jpg";

$altesbild=imagecreatefromjpeg($bild);
$neuesbild=imagecreate(16,21);
imagecopy ($neuesbild,$altesbild,0,0,0,0,16,21);
imagejpeg($neuesbild,"zaehler.jpg");

?>
</body> </html>
Die Fehlermeldung des Servers:
Warning: imagejpeg() [function.imagejpeg]: Unable to open 'zaehler0.jpg' for writing in meinPfad/image.php on line 14
Wobei "meinPfad" natürlich der komplette Pfad auf dem Webserver ist. Was sagt mir diese Fehlermeldung? Fehlt mir die Berechtigung oder mache ich etwas falsch?
Benutzeravatar
Laurin
Beiträge: 1639
Registriert: 23.09.2004 18:04
Wohnort: /dev/eth0

Beitrag von Laurin »

Sieht danach aus, also ob dein PHP-Script keine Schreibrechte hätte.
Der Fehler deutet ja darauf hin.
Now these points of data make a beautiful line.
And we're out of beta. We're releasing on time.
Benutzeravatar
redacid
Beiträge: 581
Registriert: 29.08.2004 17:06

Beitrag von redacid »

aha! Schreibrechte. Wie vergebe ich die? Einfach mit chmod? Wenn ja: welcher Wert wäre richtig?
Benutzeravatar
Ypser
XMas-Contest-Gewinner '03
Beiträge: 128
Registriert: 29.08.2004 14:35
Computerausstattung: Win7
Wohnort: Ingelheim
Kontaktdaten:

Beitrag von Ypser »

Du brauchst Schreibrechte für den Ordner, in dem das neue Bild gespeichert wird.
Wenns ein FTP-Server ist, dann musst du mit dem FTP-Client dem Ordner per "CHMOD" die Rechte "777" geben.
Wo läuft denn das Skript grad? Auf nem lokalen Server? Welches System?
Bild
Benutzeravatar
AND51
Beiträge: 5220
Registriert: 01.10.2005 13:15

Beitrag von AND51 »

Tu's nicht! Auf keinen Fall 777 !

Das würde bedeuten, jeder hätte Schreibrechte für die PHP-Datei, und da wir ja alle wisen, wie mächtig PHP ist, könnt man damit schon so einige Daten vom Server lösche oder sonstwas!

Ich erkläre kurz, wie sich die CHMOD Rechte zusammensetzen:

1. Stelle steht für den Besitzer der Datei (also für dich)
2. für bestimmte, der Datei zugeordnete Gruppen (bei einigen Providern auch für 3.)
3. Welt (heißt: alle, also auch die normalen Surfer)

Soll der Besitzer (1.) vollen Zugriff haben, dann soll er die Datei
lesen = 1
schreiben = 2
ausführen = 4
dürfen. Die Rechte werden einfach zusammen gezählt. Also voller Zugriff: 1+2+4=7, also kommt die sieben an erster Stelle.
Da bei einigen Providern die zweite Stelle gleich die dritte Stelle ist, dürfen "Gruppe" (2.) und "Welt" (3.) die Datei nur lesen (1) und ausführen (4).
1+4=5, also an den beiden Stellen eine 5.

755 bedeutet also: Du als besitzer darfst alles machen, alle anderen Menschen auf der Welt dürfen höchstens die Datei laden (also ausführen).

Dabei ist "lesen" nicht gleich "ausführen", sondern lesen bedeutet, dass der Client die Erlaubnis hat, zu erfahren, dass die Datei auf dem Server existiert. Ausführen hingegen heißt, er darf die datei sogar laden. Und schreiben heißt, er darf die Datei halt verändern und man kann schon ahnen, wohin das führen kann.

So, ich hoffe, jetzt haben alle verstanden, warum man 777 nicht nehmen sollte. Da kann man nichts, wie man denken könnte, gewinnen, sondern eher verlieren ;-).
Das beste ist halt 755. 777 sollte man höchstens nur für kurze Zeit zu Testzwecken verwenden.
PB 4.30

Code: Alles auswählen

Macro Happy
 ;-)
EndMacro

Happy End
Benutzeravatar
Ypser
XMas-Contest-Gewinner '03
Beiträge: 128
Registriert: 29.08.2004 14:35
Computerausstattung: Win7
Wohnort: Ingelheim
Kontaktdaten:

Beitrag von Ypser »

AND51 hat geschrieben:... 777 sollte man höchstens nur für kurze Zeit zu Testzwecken verwenden.
Hab ja auch nicht gesagt, dass das die endgültige Variante ist. Aber da es sich hier nur um
Übungsskripte handelt, wenn ich richtig mitgelesen habe, ist es ein "Testzweck" :wink:

Nachher natürlich was anderes nehmen, wobei es in diesem Fall egal ist, da eh nur ne Temporäre Datei.

Aber wieso willst du das Bild erst auf dem Server speichern, anstatt es direkt an den Browser zu senden?

Außerdem, And51, wieso Schreibrechte für eine PHP-Datei? Davon hat keiner gesprochen...

<edit>
Wollen wir das dann auch komplett machen ;)

Das Ausführen-Flag kannst du auch weglassen, das bezieht sich nämlich nur auf richtige ausführbare
Dateien (bei Windows .exe). Bei PHP-Skripten reicht das Lesen-Flag, denn diese Datei wird nicht ausgeführt,
sondern nur vom PHP-Parser GELESEN (und interpretiert).
Die Flags für Group und Public könntest du auch weglassen, denn wenn ein PHP-Skript ausgeführt wird, dann
immer vom PHP-Parser, und der ist automatisch "Owner".
Theoretisch würde für ein PHP-Skript also 400 ausreichen.

Das alles gilt jetzt für PHP-Skripte, aber wie schon gesagt, davon war hier nicht die Rede!

Außerdem hast du Lesen und Ausführen vertauscht, Lesen ist 4, ausführen 1. Aber gut, dass du
mal wieder was geschrieben hast :mrgreen:
</edit>
Bild
Benutzeravatar
redacid
Beiträge: 581
Registriert: 29.08.2004 17:06

Beitrag von redacid »

Ypser hat geschrieben: Aber wieso willst du das Bild erst auf dem Server speichern, anstatt es direkt an den Browser zu senden?
ich bin noch Anfänger und bei dem Versuch, es direkt an den Browser zu schicken, kam nur Zeichenmüll.
Benutzeravatar
Ypser
XMas-Contest-Gewinner '03
Beiträge: 128
Registriert: 29.08.2004 14:35
Computerausstattung: Win7
Wohnort: Ingelheim
Kontaktdaten:

Beitrag von Ypser »

Ich würde das folgendermaßen machen:
Du lagerst den PHP-Code in ein anderes Skript aus. Das ist nur dafür zuständig, das Bild zu generieren
und es an den Browser zu senden. Damit das Resultat nicht als HTML-Datei, sondern als Bild übermittelt
wird, muss der HTTP-Header geändert werden.

Das Skript sähe dann etwa so aus (mein_bilderzeugungsskript.php):

Code: Alles auswählen

<?

//Bild erzeugen

 ImageJpeg($bild);

 Header ("HTTP/1.1 200 OK", true);
 Header ("Date: ".GMDate("D, d M Y H:i:s GTM"), true);
 Header ("Server: Apache/1.3.27", true);
 Header ("Accept-Ranges: bytes", true);
 Header ("Content-Type: image/jpeg", true);
?>
Vor dem "<?" darf KEIN Zeichen sein!

Dieses Skript rufst du dann von der HTML-Datei auf, indem du es als src-Attribut eines IMG-Tags einbindest.
Ungefähr so:

Code: Alles auswählen

<img src="mein_bilderzeugungsskript.php">
Fertig. :D
Bild
DarkDragon
Beiträge: 6291
Registriert: 29.08.2004 08:37
Computerausstattung: Hoffentlich bald keine mehr
Kontaktdaten:

Beitrag von DarkDragon »

Ein kleines chmod-tool:

Code: Alles auswählen

;- Window Constants
;
Enumeration
  #Window_0
EndEnumeration

;- Gadget Constants
;
Enumeration
  #Text_00
  #Text_10
  #Text_20
  #Text_30
  #Text_40
  #Text_50
  #USER_READ
  #GROUP_READ
  #WORLD_READ
  #USER_WRITE
  #GROUP_WRITE
  #WORLD_WRITE
  #USER_RUN
  #GROUP_RUN
  #WORLD_RUN
  #NUMERIC
  #WORDS
  #OK
EndEnumeration


Procedure.s Open_Chmod(chmod.s)
  If OpenWindow(0, 0, 0, 320, 240,  #PB_Window_SystemMenu | #PB_Window_TitleBar | #PB_Window_ScreenCentered , "CHMOD")
    If CreateGadgetList(WindowID())
      TextGadget(#Text_00, 10, 40, 80, 20, "Owner:")
      TextGadget(#Text_10, 10, 70, 80, 20, "Group:")
      TextGadget(#Text_20, 10, 100, 80, 20, "World:")
      TextGadget(#Text_30, 120, 10, 50, 20, "Read", #PB_Text_Center)
      TextGadget(#Text_40, 190, 10, 50, 20, "Write", #PB_Text_Center)
      TextGadget(#Text_50, 260, 10, 50, 20, "Run", #PB_Text_Center)
      
      CheckBoxGadget(#USER_READ, 140, 40, 20, 20, "")
      CheckBoxGadget(#GROUP_READ, 140, 70, 20, 20, "")
      CheckBoxGadget(#WORLD_READ, 140, 100, 20, 20, "")
      CheckBoxGadget(#USER_WRITE, 210, 40, 20, 20, "")
      CheckBoxGadget(#GROUP_WRITE, 210, 70, 20, 20, "")
      CheckBoxGadget(#WORLD_WRITE, 210, 100, 20, 20, "")
      CheckBoxGadget(#USER_RUN, 280, 40, 20, 20, "")
      CheckBoxGadget(#GROUP_RUN, 280, 70, 20, 20, "")
      CheckBoxGadget(#WORLD_RUN, 280, 100, 20, 20, "")
      
      StringGadget(#NUMERIC, 10, 150, 300, 20, "000", #ESB_DISABLE_RIGHT)
      StringGadget(#WORDS, 10, 180, 300, 20, chmod, #ESB_DISABLE_RIGHT)
      
      ButtonGadget(#OK, 10, 210, 300, 20, "OK")
      
      If Trim(chmod) = ""
        SetGadgetText(#WORDS, "----------")
      EndIf
      
      Repeat
      Event = WaitWindowEvent()
      Select Event
      Case #PB_Event_CloseWindow
        Q = 1
      Case #PB_Event_Gadget
        GID = EventGadgetID()
        If GID = #OK
          chmod = GetGadgetText(#NUMERIC)
          Q = 1
        ElseIf GID >= #USER_READ And GID <= #WORLD_RUN
          User1.s = Str(GetGadgetState(#USER_READ)*4+GetGadgetState(#USER_WRITE)*2+GetGadgetState(#USER_RUN)*1)
          Group1.s = Str(GetGadgetState(#GROUP_READ)*4+GetGadgetState(#GROUP_WRITE)*2+GetGadgetState(#GROUP_RUN)*1)
          World1.s = Str(GetGadgetState(#WORLD_READ)*4+GetGadgetState(#WORLD_WRITE)*2+GetGadgetState(#WORLD_RUN)*1)
          
          SetGadgetText(#NUMERIC, User1+Group1+World1)
          
          Num.s = GetGadgetText(#NUMERIC)
          
          User2.l = Val(Mid(Num, 1, 1))
          Group2.l = Val(Mid(Num, 2, 1))
          World2.l = Val(Mid(Num, 3, 1))
          
          Txt.s = GetGadgetText(#WORDS)
          
          If User2 & 4
          PokeB(@Txt+1, 'r')
          Else
          PokeB(@Txt+1, '-')
          EndIf
          If User2 & 2
          PokeB(@Txt+2, 'w')
          Else
          PokeB(@Txt+2, '-')
          EndIf
          If User2 & 1
          PokeB(@Txt+3, 'x')
          Else
          PokeB(@Txt+3, '-')
          EndIf
          
          If Group2 & 4
          PokeB(@Txt+4, 'r')
          Else
          PokeB(@Txt+4, '-')
          EndIf
          If Group2 & 2
          PokeB(@Txt+5, 'w')
          Else
          PokeB(@Txt+5, '-')
          EndIf
          If Group2 & 1
          PokeB(@Txt+6, 'x')
          Else
          PokeB(@Txt+6, '-')
          EndIf
          
          If World2 & 4
          PokeB(@Txt+7, 'r')
          Else
          PokeB(@Txt+7, '-')
          EndIf
          If World2 & 2
          PokeB(@Txt+8, 'w')
          Else
          PokeB(@Txt+8, '-')
          EndIf
          If World2 & 1
          PokeB(@Txt+9, 'x')
          Else
          PokeB(@Txt+9, '-')
          EndIf
          
          SetGadgetText(#WORDS, Txt)
        ElseIf GID = #NUMERIC
          Num.s = GetGadgetText(#NUMERIC)
          
          User2.l = Val(Mid(Num, 1, 1))
          Group2.l = Val(Mid(Num, 2, 1))
          World2.l = Val(Mid(Num, 3, 1))
          
          SetGadgetState(#USER_READ  , User2 & 4)
          SetGadgetState(#USER_WRITE , User2 & 2)
          SetGadgetState(#USER_RUN   , User2 & 1)
          
          SetGadgetState(#GROUP_READ , Group2 & 4)
          SetGadgetState(#GROUP_WRITE, Group2 & 2)
          SetGadgetState(#GROUP_RUN  , Group2 & 1)
          
          SetGadgetState(#WORLD_READ , World2 & 4)
          SetGadgetState(#WORLD_WRITE, World2 & 2)
          SetGadgetState(#WORLD_RUN  , World2 & 1)
          
          Txt.s = GetGadgetText(#WORDS)
          
          If User2 & 4
          PokeB(@Txt+1, 'r')
          Else
          PokeB(@Txt+1, '-')
          EndIf
          If User2 & 2
          PokeB(@Txt+2, 'w')
          Else
          PokeB(@Txt+2, '-')
          EndIf
          If User2 & 1
          PokeB(@Txt+3, 'x')
          Else
          PokeB(@Txt+3, '-')
          EndIf
          
          If Group2 & 4
          PokeB(@Txt+4, 'r')
          Else
          PokeB(@Txt+4, '-')
          EndIf
          If Group2 & 2
          PokeB(@Txt+5, 'w')
          Else
          PokeB(@Txt+5, '-')
          EndIf
          If Group2 & 1
          PokeB(@Txt+6, 'x')
          Else
          PokeB(@Txt+6, '-')
          EndIf
          
          If World2 & 4
          PokeB(@Txt+7, 'r')
          Else
          PokeB(@Txt+7, '-')
          EndIf
          If World2 & 2
          PokeB(@Txt+8, 'w')
          Else
          PokeB(@Txt+8, '-')
          EndIf
          If World2 & 1
          PokeB(@Txt+9, 'x')
          Else
          PokeB(@Txt+9, '-')
          EndIf
          
          SetGadgetText(#WORDS, Txt)
        Else
          Word.s = GetGadgetText(#WORDS)
          
          User1.s = Mid(Word, 2, 3)
          Group1.s = Mid(Word, 5, 3)
          World1.s = Mid(Word, 8, 3)
          
          If Mid(User1, 1, 1)  = "r"                             : SetGadgetState(#USER_READ  , 1)  : Else : SetGadgetState(#USER_READ  , 0)  : EndIf
          If Mid(User1, 2, 1)  = "w"                             : SetGadgetState(#USER_WRITE , 1)  : Else : SetGadgetState(#USER_WRITE , 0)  : EndIf
          If Mid(User1, 3, 1)  = "x" Or Mid(User1, 3, 1)  = "s"  : SetGadgetState(#USER_RUN   , 1)  : Else : SetGadgetState(#USER_RUN   , 0)  : EndIf
          
          If Mid(Group1, 1, 1) = "r"                             : SetGadgetState(#GROUP_READ  , 1) : Else : SetGadgetState(#GROUP_READ  , 0) : EndIf
          If Mid(Group1, 2, 1) = "w"                             : SetGadgetState(#GROUP_WRITE , 1) : Else : SetGadgetState(#GROUP_WRITE , 0) : EndIf
          If Mid(Group1, 3, 1) = "x" Or Mid(Group1, 3, 1)  = "s" : SetGadgetState(#GROUP_RUN   , 1) : Else : SetGadgetState(#GROUP_RUN   , 0) : EndIf
          
          If Mid(World1, 1, 1) = "r"                             : SetGadgetState(#WORLD_READ  , 1) : Else : SetGadgetState(#WORLD_READ  , 0) : EndIf
          If Mid(World1, 2, 1) = "w"                             : SetGadgetState(#WORLD_WRITE , 1) : Else : SetGadgetState(#WORLD_WRITE , 0) : EndIf
          If Mid(World1, 3, 1) = "x" Or Mid(World1, 3, 1)  = "s" : SetGadgetState(#WORLD_RUN   , 1) : Else : SetGadgetState(#WORLD_RUN   , 0) : EndIf
        EndIf
      EndSelect
      Until Q = 1
      
    EndIf
  EndIf
  ProcedureReturn chmod
EndProcedure

Open_Chmod("")
Angenommen es gäbe einen Algorithmus mit imaginärer Laufzeit O(i * n), dann gilt O((i * n)^2) = O(-1 * n^2) d.h. wenn man diesen Algorithmus verschachtelt ist er fertig, bevor er angefangen hat.
Benutzeravatar
redacid
Beiträge: 581
Registriert: 29.08.2004 17:06

Beitrag von redacid »

Danke Ypser, ich habe es nun dank deiner Beschreibung und SelfPHP hinbekommen, die Grafik direkt anzeigen zu lassen. Hat viel Schweiß gekostet, aber wenn man ab und an ein Erfolgserlebnis hat, ist man ja schon zufrieden...

Und Daniel, auch dir danke ich. Nettes Programm. Läuft auch unter MacOS. Allerdings fehlt mir dort eine Konstante: #ESB_Disable_Right. Woher kommt diese und welchen Wert hat sie?
Antworten