Just nu i M3-nätverket
Gå till innehåll

problem med att hämta id när register_globals är off


savbrink

Rekommendera Poster

Har ett problem med att delete funktionen inte fungerar sedan register_globals sattes till off. Delete funktionen fungerar men det följer inte med något id. Har frågat runt men ingen har kunnat hjälpa mig än. Jag har testat med att sätta ett id för att kolla om delefunktion fungerar och det gör den. Men det verkar vara helt omöjligt att få med id:et.

 

Tackar på förhand om någon kan hjälpa mig med detta.

 

<?

extract($_POST);

$conn=mysql_connect("localhost", "XXXX", "XXXX");

$rs=mysql_select_db("XXXXXX", $conn);

 

if(isset($edit_news) and $action=="add") {

$sql="insert into note (header, link, text) values (\"$header\", \"$link\", \"$text\")";

$rs=mysql_query($sql, $conn);

}

 

 

if($action=="delete") {

$sql="delete from note where id=$_GET[id]";

$rs=mysql_query($sql, $conn);

}

 

 

print("<table border=1 cellpadding=5 cellspacing=0 bordercolor=#000000>");

print("<tr><td bgcolor=#CCCCCC>Rubriktext</td><td bgcolor=#CCCCCC>Länktext</td> <td bgcolor=#CCCCCC>Radera?</td>");

 

$sql="select * from note where id >1";

$rs=mysql_query($sql, $conn);

while($row=mysql_fetch_array($rs)) {

 

echo ("<tr><td>");

echo("<P><B>".$row["header"]."</B><BR>");

echo ("</td>");

 

echo ("<td>");

echo("<P><B>".$row["link"]."</B><BR>");

echo ("</td>");

 

echo ("<td>");

$tmp_id=$row["id"];

echo("<A HREF=new_note.php?id=$tmp_id&action=delete>Radera Anslag?</A>&nbsp;&nbsp");

echo ("</td></tr>");

 

}

 

echo("<form action=".$_SERVER['PHP_SELF']." method=\"post\">

<B>Rubriktext</B>

<BR><INPUT TYPE=text NAME=header SIZE=40><P>

<B>Text</B><BR>

<TEXTAREA TYPE=text NAME=text COLS=50 ROWS=15>nyhet</TEXTAREA><P>

<B>Länktext</B><BR>

<INPUT TYPE=text NAME=link SIZE=15 maxlength=15><P>

 

<INPUT TYPE=hidden NAME=action VALUE=\"add\">

 

<INPUT TYPE=submit NAME=edit_news VALUE=Spara>

</FORM>

 

");

 

 

Länk till kommentar
Dela på andra webbplatser

Det är ju inte helt självklart vad du inte anser fungerar men du har ett flertal konstigheter...

t.ex följande:

$sql="delete from note where id=$_GET[id]";

Du menar förmodligen $_GET['id'] och inte $_GET[id], föreslår därför att du skriver så här:

 $sql='[color="#ff0000"]delete[/color] from note where id='.[color="#0000ff"]$[/color]_GET['id'];

 

Tänk också på att det är gansk riskabelt att ta det man får in som querystring och skicka det rakt in i en delete-sats till databasen... Vad tror du händer om någon skickar in query-strängen "?id=id" (rätt svar: du kommer att göra en "delete from note where id=id" och tömma databasen).

 

Vore det dessutom inte bättre att använda $_POST['edit_news'] istället för extract()? Då skulle du ju inte behöva vandra i ovisshet om vad dina automagiskt skapade variabler heter?

 

Länk till kommentar
Dela på andra webbplatser

Det går hur bra som helst att skriva $_GET[id] istället för $_GET['id']. På så sätt slipper man konkatenera strängar, vilket sparar serverkraft. Dock ska man alltid, som du säger, kontrollera indata från querystringar och formulär.

 

Länk till kommentar
Dela på andra webbplatser

Det går hur bra som helst att skriva $_GET[id] istället för $_GET['id']. På så sätt slipper man konkatenera strängar, vilket sparar serverkraft.

Konkatenering av en variabel och en konstantsträng borde inte vara kostsammare än att bygga en expression-sträng (och du har nog rätt i att det fungerar med [id] i just strängar), tvärt om.

 

Länk till kommentar
Dela på andra webbplatser

Jag har testat på massvis utav olika sätt. Som koden ser ut nu är ett tips ifrån ett annat forum.

 

Jag vet att det inte är så smart att id i querystringen till en deletesats men det är inte så många poster i databasen åt gången så det får bli ett senare problem. Men jag förstår inte hur jag enklast kan läsa id problemet?

 

Länk till kommentar
Dela på andra webbplatser

Men jag förstår inte hur jag enklast kan läsa id problemet?

Börja med att berätta vad problemet är, lyckas du inte göra en korrekt sträng? (lätt att se genom att skriva ut den med ett "echo $sql;") eller tas det inte bort några rader?

Vad är id i databasen? ett heltalsfällt?

Får du något fel från databasen (skriv "echo mysql_error();" raden efter din mysql_query()).

 

Ingen kan mer än gissa vad "det blir fel" betyder. Jag tycker fortfarande att du ska göra rätt:

$sql='[color="#ff0000"]delete[/color] from note where id='[color="#0000ff"]$[/color]_GET['id'];

 

Länk till kommentar
Dela på andra webbplatser

Konkatenering av en variabel och en konstantsträng borde inte vara kostsammare än att bygga en expression-sträng (och du har nog rätt i att det fungerar med [id] i just strängar), tvärt om.

 

Borde eller inte, det går långsammare att konkatenera.

 

Länk till kommentar
Dela på andra webbplatser

Eller varför inte använda sig av sprintf?

 

$sql = [color="#ff0000"]sprintf[/color]('[color="#ff0000"]delete[/color] FROM note WHERE id = %d', [color="#0000ff"]$[/color]_GET['id']);

Detta ser till så att du bara kan få in en siffra där i vilket är trevligt ur säkerhetssynpunkt. Dock kan det blir knas om man blandar in bokstäver i det hela då sprintf bara kapar om det kommer något annat än siffror i variabeln du kör in i SQL frågan. Därför kan det kanske vara läge att kolla så att det verkligen bara är siffror du får in till frågan med till exempel is_int metoden, om det inte är siffror kan du då döda scriptet och logga vad som hände innan något dumt händer.

 

Hur som helst borde du alltid kolla indatat vid SQL frågor. Och egentligen borde du kanske inte ens ta indata från $_GET då det rör sig om en delete sats eftersom det är en riktigt utsatt sqlfråga. Oavsett om du kollar indatat så att det verkligen är en siffra så säger ju inte det att en dum användare byter ut den siffran mot något annat och på så vis raderar information som du inte hade tänkt dig att radera.

 

--

"I killed my dinner with karate -

kick ´em in the face, taste the body;

shallow work is the work that I do." -Joanna Newsom

 

Länk till kommentar
Dela på andra webbplatser

Lite off topic kanske, men jag stötte på en webbplats som kostat flera hundra tusen för ett företag, skapad av en ganska etablerad webbbyrå. Där kontrolleras aldrig indata från varken post eller get. Då blir man lite mörkrädd.

 

Det är väl inget fel i att använda get till delete-frågor, så länge man kontrollerar att indatan är av rätt format, och att användaren verkligen har rätt att ta bort just den posten.

 

Länk till kommentar
Dela på andra webbplatser

och att användaren verkligen har rätt att ta bort just den posten.

Där slog du huvudet på spiken, det var det jag ville komma fram till men jag kom inte på att skriva det själv! :)

 

--

"I killed my dinner with karate -

kick ´em in the face, taste the body;

shallow work is the work that I do." -Joanna Newsom

 

Länk till kommentar
Dela på andra webbplatser

Lite off topic kanske, men jag stötte på en webbplats som kostat flera hundra tusen för ett företag, skapad av en ganska etablerad webbbyrå.

Det är ju fortfarande nästan mer regel än undantag att folk anställer tomtar som inte kan det de håller på med.

 

Det är väl inget fel i att använda get till delete-frågor, så länge man kontrollerar att indatan är av rätt format

Naturligtvis inte, effekten blir ju den samma som om du lägger det i en annan variabel.

 

 

Länk till kommentar
Dela på andra webbplatser

Borde eller inte, det går långsammare att konkatenera.

Eller hur?

 

Världens enklaste test

timer.php

<?[color="#0000ff"]php[/color]
$t0=[color="#ff0000"]microtime[/color]([color="#ff8C00"]TRUE[/color]);
[color="#0000ff"]for[/color]($i=0;$i++;$i<1000000) {
  $sql="[color="#ff0000"]delete[/color] from note where id=[color="#0000ff"]$[/color]_GET[id]";
}
$t1=[color="#ff0000"]microtime[/color]([color="#ff8C00"]TRUE[/color]);
[color="#0000ff"]echo[/color] "Tid för kostsamt sätt: ".($t1-$t0)."<br>";

$t0=[color="#ff0000"]microtime[/color]([color="#ff8C00"]TRUE[/color]);
[color="#0000ff"]for[/color]($i=0;$i++;$i<1000000) {
  $sql='[color="#ff0000"]delete[/color] from note where id='.[color="#0000ff"]$[/color]_GET['id'];
}
$t1=[color="#ff0000"]microtime[/color]([color="#ff8C00"]TRUE[/color]);
[color="#0000ff"]echo[/color] "Tid för konkatenering: ".($t1-$t0)."<br>";
?>

 

Ropar på den med http://localhost/timer.php?id=hepp, förvisso på en jätteskruttig gammal häck men här är resultatet:

 

Tid för kostsamt sätt: 0.005345

Tid för konkatenering: 2.9999999999999E-05

 

Konkateneringen kanske inte var så långsam trots allt...

 

Länk till kommentar
Dela på andra webbplatser

Märkligt. När jag testade det, visserligen med konkatenering av strängar både före och efter variabeln, så blev konkateneringen i snitt en tiondel långsammare.

 

Nåja, detta är ändå hårklyveri, jämfört med hur mycket serverkraft databastraffiken snor så spelar det ingen större roll om man konkatenerar eller inte. =)

 

Länk till kommentar
Dela på andra webbplatser

så blev konkateneringen i snitt en tiondel långsammare.

Min gissning är att du använde "-strängar och inte '-strängar... Då måste ju php göra samma extrajobb i bägge fallen.

 

Länk till kommentar
Dela på andra webbplatser

Min gissning är att du använde "-strängar och inte '-strängar... Då måste ju php göra samma extrajobb i bägge fallen.

Nepp, använde ' för konkateneringen, på båda sidor. Inga " inblandade.

 

Länk till kommentar
Dela på andra webbplatser

Ett så pass kort (tidmässigt) test kan ju bli väldigt missvisande eftersom man inte vet vad datorn pysslar med under tiden.

 

Se till att varje deltest tar t ex 10 sekunder att köra och se till att datorn är helt nerlastad under tiden så kanske det blir lättare att jämföra.

 

Länk till kommentar
Dela på andra webbplatser

Ett så pass kort (tidmässigt) test kan ju bli väldigt missvisande eftersom man inte vet vad datorn pysslar med under tiden.

Den risken minskar avsevärt om man ser samma sak körning efter körning...

 

Se till att varje deltest tar t ex 10 sekunder att köra och se till att datorn är helt nerlastad under tiden så kanske det blir lättare att jämföra

Om datorn är helt lastad så blir det absolut missvisande, du har ingen som helst kontroll över när hur preemptad processen blir.

 

Du har hur som helst, jag måste haft hjärnsläpp när jag skrev koden för den är grymt felaktig:

 

Korrigerad kod:

<?[color="#0000ff"]php[/color]
[color="#0000ff"]function[/color] [color="#ff0000"]microtime[/color]_[color="#0000ff"]float[/color]()
{
   [color="#0000ff"]list[/color]($usec, $sec) = [color="#ff0000"]explode[/color](" ", [color="#ff0000"]microtime[/color]());
   [color="#0000ff"]return[/color] (([color="#0000ff"]float[/color])$usec + ([color="#0000ff"]float[/color])$sec);
}

$t0=[color="#ff0000"]microtime[/color]_[color="#0000ff"]float[/color]();

[color="#0000ff"]for[/color]($i=0;$i<1000000;$i++) {
  $sql="[color="#ff0000"]delete[/color] from note where id=[color="#0000ff"]$[/color]_GET[id]";
}
$t1=[color="#ff0000"]microtime[/color]_[color="#0000ff"]float[/color]();
[color="#0000ff"]echo[/color] "Tid för kostsamt sätt: ".[color="#ff0000"]sprintf[/color]("%0.10f", ($t1-$t0))."<br>";

$t0=[color="#ff0000"]microtime[/color]_[color="#0000ff"]float[/color]();
[color="#0000ff"]for[/color]($i=0;$i<1000000;$i++) {
  $sql='[color="#ff0000"]delete[/color] from note where id='.[color="#0000ff"]$[/color]_GET['id'];
}
$t1=[color="#ff0000"]microtime[/color]_[color="#0000ff"]float[/color]();
[color="#0000ff"]echo[/color] "Tid för konkatenering: ".[color="#ff0000"]sprintf[/color]("%0.10f", ($t1-$t0))."<br>";
?>

 

Ger på samma burk:

Tid för kostsamt sätt: 11.5878200531

Tid för konkatenering: 3.9080297947

 

Testade med lite olika php-versioner på lite olika arkitekturer och resultatet blir likvärdigt överallt.

 

[inlägget ändrat 2005-10-01 13:23:31 av fhe]

Länk till kommentar
Dela på andra webbplatser

Den risken minskar avsevärt om man ser samma sak körning efter körning...

 

Jo så sant!

 

Vad jag menade var att om det man tar tid på tar "för kort tid" kan andra saker som ligger utanför och stör påverka resultatet till större del än om det man mäter tar "lång" tid. Jag vet inte hur snabb t ex XP är på context switching, men har man otur kanske man får en context switch mitt i testet och då kan det påverka relativt sett mycket.

 

Jaja, det var väl kanske inte så noga.

 

Men nu blev det ju samma resultat gång efter gång så då gick det väl bra ändå.

 

Om datorn är helt lastad så blir det absolut missvisande, du har ingen som helst kontroll över när hur preemptad processen blir.

 

Nja, jag menade att datorn ska vara 100% (cpu) upptagen med just det du mäter. Om den pysslar med annat under tiden vet man ju inte vad man mätit på.

 

Länk till kommentar
Dela på andra webbplatser

Börja med att berätta vad problemet är, lyckas du inte göra en korrekt sträng? (lätt att se genom att skriva ut den med ett "echo $sql;") eller tas det inte bort några rader?

Vad är id i databasen? ett heltalsfällt?

Får du något fel från databasen (skriv "echo mysql_error();" raden efter din mysql_query()).

 

Ingen kan mer än gissa vad "det blir fel" betyder. Jag tycker fortfarande att du ska göra rätt:

$sql='delete from note where id='$_GET['id']

 

Deletesatsen funger det har jag testat, det skickas även med id i querystringen.

<A HREF=new_note.php?id=$tmp_id&action=delete>Radera innan räckte det med att skriva =$ID för att få ut värdet som man skickade med i querystringen men det gå tydligen inte att göra med register_globals off.

 

Men går det att hämta queystringen överhuvudtaget som koden är skriven nu? Om inte hur man kan man gör istället?

 

 

Länk till kommentar
Dela på andra webbplatser

Deletesatsen funger det har jag testat, det skickas även med id i querystringen.

Vad jag menade var att skriva ut delete-raden som den ser ut EFTER att du har klistrat ihop den med det du får med querysträngen, annars har du ju ingen som helst möjlighet att avgöra vad som är fel.

 

Men går det att hämta queystringen överhuvudtaget som koden är skriven nu? Om inte hur man kan man gör istället?

Använd $_GET['id']. Det är rätt sätt och kommer att fungera oavsett om du har register globals på eller av (och du kan glatt räkna med att "av" är det läge som gäller, det är ett gammalt farligt och onödigt sätt att ha sin php konfigurerad).

 

Länk till kommentar
Dela på andra webbplatser

Hur gör man för att skriva ut deletesatsen efter querystringen är med?

 

I asp så skulle man ju kunna lösa det här problemet med

 

id = requset.querystring.tostring varför finns finns inte det med i PHP längre det är ju inte bara en säkerhetsrisk. Man skulle ju kunna använda det med vanliga länkar, bilder eller något också.

 

 

 

 

 

Länk till kommentar
Dela på andra webbplatser

Hur gör man för att skriva ut deletesatsen efter querystringen är med?

"echo $sql;" raden efter att du skapat variabeln är väl enklast.

 

$sql='[color="#ff0000"]delete[/color] from note where id='.[color="#0000ff"]$[/color]_GET['id'];
[color="#0000ff"]echo[/color] $sql;

 

id = requset.querystring.tostring varför finns finns inte det med i PHP

Det gör det väl, vad är problemet?

 

Du hittar precis hela query-strängen i $_SERVER['QUERY_STRING'] och om det bara är id-delen du vill komma åt så hittar du den i $_GET['id'].

Det är varken svårare eller speciellt annorlunda jämfört med hur det fungerar i ASP, bara andra namn.

 

[inlägget ändrat 2005-10-06 16:56:47 av fhe]

Länk till kommentar
Dela på andra webbplatser

Arkiverat

Det här ämnet är nu arkiverat och är stängt för ytterligare svar.

×
×
  • Skapa nytt...