dotarMedlem sedan okt. 2002117 inlägg Hejsan, jag håller på att koda en gästbok som använder sig av en textfil som "databas".
Jag håller på med en adminfunktion, och har nu kommit till delen där man skall kunna ta bort enskilda inlägg.
Jag börjar med att göra en länk..
echo "<a href='delete.php?id=" . $row . ">[Ta bort]</a>"
Där $row är själva raden i filen.
Raden ser ut ungefär så här: "dotar|Meddelande|2004-26-11 - 18:57|webmaster@dotar.net|http://www.dotar.net|192.168.0.6"
Nu vill jag på något sätt gå in i filen (gb.txt) och ta bort endast denna raden. Hur gör jag det på bästa sätt?
Jag antar att man får börja ungefär så här:
if (!$handle = fopen($filename, 'r+')){
echo "Error: Filen kunde inte öppnas";
}
else
Men sedan?
ViktorMedlem sedan aug. 20021 752 inlägg Tråd flyttad från "Programmering - Övrigt".
/Viktor
SnakesMedlem sedan okt. 2004392 inlägg hur kan en rad möjligt vis se ut?
dotarMedlem sedan okt. 2002117 inlägg
dotar|Meddelande|2004-26-11 - 18:57|webmaster@dotar.net|http://www.dotar.net|192.168.0.6
Som jag skrev i det första inlägget ;)
Alltså;
namn|meddelande|datum|mail|hemsida|IP
fiddlerMedlem sedan juli 20023 617 inlägg HansenMedlem sedan aug. 2000374 inlägg Det finns flera olika sätt, här är en variant:
<?
$fn_read = "./data";
do {
$fh_read = fopen( $fn_read, "r" )
or die( "Failed to open file: $fn_read\n" );
flock( $fh_read, LOCK_EX )
or die( "Failed to get exclusive lock on file: $fn_read\n" );
$fn_stat = stat($fn_read);
$fh_stat = fstat($fh_read);
} while ( $fn_stat[ino] != $fh_stat[ino] );
$fn_write = tempnam( "./", "data-" )
or die( "Failed to create tempoary file\n" );
$fh_write = fopen( $fn_write, "w" )
or die( "Failed to open tempoary file: $fn_write\n" );
flock( $fh_write, LOCK_EX )
or die( "Failed to get exclusive lock on tempoary file: $fn_write\n" );
while ( !feof($fh_read) ) {
$line = fgets($fh_read);
# I don't like apples ;)
if ( ! preg_match( '/^apple$/i', $line ) ) {
fwrite( $fh_write, $line ) === FALSE
and die( "Failed to write to tempoary file: $fn_write\n" );
}
}
rename( $fn_write, $fn_read )
or die( "Failed to rename: $fn_write to: $fn_read\n" );
fclose($fh_read)
or die( "Failed to close: $fn_read\n" );
fclose($fh_write)
or die( "Failed to close: $fn_write\n" );
?>
Så länge applikationen låser LOCK_SH vid läs operationer och använder ovan kod vid skrivning så kommer operationen vara atomisk, dvs antingen genomförs operationen eller inte.
/red: Förtydligande
HansenMedlem sedan aug. 2000374 inlägg
fiddler skrev:
Här kan du hitta lite matnyttigt: http://www.a-kok.com/php/lagratext.php
Vad du än gör, använd inte dom kodsnuttarna!! Det kommer leda till korrupta datafiler!
dotarMedlem sedan okt. 2002117 inlägg Tack för hjälpen, men dessvärre förtod jag inte så mycket :/
Hur ska jag använda mig av koden?
Var ska den ligga?
SnakesMedlem sedan okt. 2004392 inlägg För att detta script ska funka så måste du lägga in ett id!
Alltså du måste lägga in nåt unikt helt enkelt.... hur gör man det?
varje gång någon skriver ett meddelande så lägger du in ett slumpat tal
$id = rand(0, 20);
Strukturen måste se ur så här
id|namn|meddelande|datum|mail|hemsida|IP
Detta lägger du i en ny fil som heter delete.php
$removeid = $_GET['id'];
$id="";
$itemsdb="textfilen.txt";
$array = file("$itemsdb"); // läs in filen
$fw = fopen("$itemsdb", "w"); // öppna filen för skrivning
flock($fw, LOCK_EX); // lås filen
$i=0;
while ($i < count($array)) {
list($id,$namn,$meddelande,$datum,$mail,$hemsida,$IP) = explode('|',$array[$i]);
if ($removeid != $id) { // skriv in alla rader utom den vi ska ta bort
fputs($fw,chop($array[$i]) . "\n");
}
$i++;
}
flock($fw, LOCK_UN); // lås upp filen
fclose($fw); // stäng filen
För att senare radera nåt så kör du bara med
echo "<a href='delete.php?id=" . $row . ">[Ta bort]</a>"
alltså som du ville!!
Har du problem med nåt... kom tillbaka hit!
dotarMedlem sedan okt. 2002117 inlägg Tack så jättemycket.
Det där ser ut att fungera, testar det.
Kommer tillbaka om det inte gör det ;)
tack.
edit: tror du att det räcker med 20?
edit2: Kom på en grej.. Om man använder rand() blir det väl inte ett unikt nummer? Samma nummer akn väl komma igen?
edit3: tror du det är säkert att använda sig av
$id = rand();
Då slumpar den väl fram ett tag mellan min- och maxvärdet..?
SkarreMedlem sedan apr. 20012 427 inlägg Du skulle också kunna generera en md5-hash baserad på exempelvis aktuell tid, namn och ip-nummer.
md5(time().$name.$ip)
dotarMedlem sedan okt. 2002117 inlägg Skarre: Tack så mycket, det borde nog fungera ;)
dotarMedlem sedan okt. 2002117 inlägg Hmm.. jag har testat den på internet nu (den funkar lokalt..)
När jag loggar in på admin.php får jag dessa fellmeddelanden:
Warning: session_start(): Cannot send session cookie - headers already sent by (output started at x:\rafiiki.com\www\dotar\gb\admin.php:13) in x:\rafiiki.com\www\dotar\gb\admin.php on line 41
Warning: session_start(): Cannot send session cache limiter - headers already sent (output started at x:\rafiiki.com\www\dotar\gb\admin.php:13) in x:\rafiiki.com\www\dotar\gb\admin.php on line 41
Warning: Cannot modify header information - headers already sent by (output started at x:\rafiiki.com\www\dotar\gb\admin.php:13) in x:\rafiiki.com\www\dotar\gb\admin.php on line 43
http://www.rafiiki.com/dotar/gb/index.php
Usr: dotar
Psw: admin
Vad kan vara fel?
Så här ser admin.php ut:
if(@$_GET['login'] == "yes"){
if($_POST['user'] == "$usr"){
if($_POST['losen'] == "$psw"){
session_start();
$_SESSION['admin']= "online";
header("Location: admin2.php");
}
else{
echo "<center><div class='text'>Fel lösen <br><a href='admin.php'><Försök igen></a></div></center>";
}
}
else{
echo "<center><div class='text'>Fel användare <br><a href='admin.php'><Försök igen></a></div></center>";
}
}
HansenMedlem sedan aug. 2000374 inlägg
Snakes skrev:
[...]
$removeid = $_GET['id'];
$id="";
$itemsdb="textfilen.txt";
$array = file("$itemsdb"); // läs in filen
$fw = fopen("$itemsdb", "w"); // öppna filen för skrivning
flock($fw, LOCK_EX); // lås filen
$i=0;
while ($i < count($array)) {
list($id,$namn,$meddelande,$datum,$mail,$hemsida,$IP) = explode('|',$array[$i]);
if ($removeid != $id) { // skriv in alla rader utom den vi ska ta bort
fputs($fw,chop($array[$i]) . "\n");
}
$i++;
}
flock($fw, LOCK_UN); // lås upp filen
fclose($fw); // stäng filen
[...]
Medans du väntar på ett exklusivt lås så kan en annan process redan förändrat datan, vilket leder till korrupt data.
Eller ännu värre, vad händer om processen dör medan du skriver till filen?
SnakesMedlem sedan okt. 2004392 inlägg Hansen.... sluta tänka.... softa... Och så är det bara att lägga till or die.... ta det lungt...
dotar infoga hela admin.php
dotarMedlem sedan okt. 2002117 inlägg <!doctype html public "-//W3C//DTD HTML 4.0 //EN">
<html>
<head>
<title>dotar's GB [admin]</title>
<link href="style.css" rel="stylesheet" type="text/css">
</head>
<body bgcolor="#FAFAFA">
<center><h1>dotar's GB</h1></center>
<form action='admin.php?login=yes' method='POST' class='text'>
<table align='center' cellspacing='0' cellpadding='5' width='400' class='tabell'>
<tr align='center'>
<td>
Användarnamn:<br>
<input type='text' name='user'>
<br><br>
Lösenord:<br>
<input type='password' name='losen'>
<br><br>
<input type='submit' value='Logga in'>
</td>
</tr>
</table>
</form>
<?php
include("settings.php");
if(@$_GET['login'] == "yes"){
if($_POST['user'] == "$usr"){
if($_POST['losen'] == "$psw"){
session_start();
$_SESSION['admin']= "online";
header("Location: admin2.php");
}
else{
echo "<center><div class='text'>Fel lösen <br><a href='admin.php'><Försök igen></a></div></center>";
}
}
else{
echo "<center><div class='text'>Fel användare <br><a href='admin.php'><Försök igen></a></div></center>";
}
}
?>
</body>
</html>
Med HTML'en också :)
SnakesMedlem sedan okt. 2004392 inlägg men det funkar ju bara bra :D
kolla på http://www.rafiiki.com/dotar/gb/admin2.php
det som är fel är att den inte kan skicka dig vidare!
header("Location: admin2.php");
för att kanske du redan har en header på i settings....
Men iaf... ta bort funkar bara bra.!
tog precis bort mitt eget inlägg och den gick bort... men fick samma header fel!
Infoga settings.php :D
dotarMedlem sedan okt. 2002117 inlägg Nee.. har ingen header..
<?php
//Användarnamn
$usr = "dotar";
//Lösenord
$psw = "admin";
//Filnamn
$filename = "gb.txt";
//Datumformat
$date = date("Y-j-n - H:i");
//Ta reda på IP (Även genom proxy)
function getip() {
if (isSet($_SERVER)) {
if (isSet($_SERVER["HTTP_X_FORWARDED_FOR"])) {
$realip = $_SERVER["HTTP_X_FORWARDED_FOR"];
} elseif (isSet($_SERVER["HTTP_CLIENT_IP"])) {
$realip = $_SERVER["HTTP_CLIENT_IP"];
} else {
$realip = $_SERVER["REMOTE_ADDR"];
}
} else {
if ( getenv( 'HTTP_X_FORWARDED_FOR' ) ) {
$realip = getenv( 'HTTP_X_FORWARDED_FOR' );
} elseif ( getenv( 'HTTP_CLIENT_IP' ) ) {
$realip = getenv( 'HTTP_CLIENT_IP' );
} else {
$realip = getenv( 'REMOTE_ADDR' );
}
}
//return $realip;
}
@$ip = gethostbyname($realip);
$long = ip2long($ip);
?>
SnakesMedlem sedan okt. 2004392 inlägg Var det så innan du körde med delete grejen?
HansenMedlem sedan aug. 2000374 inlägg
Snakes skrev:
[...]Och så är det bara att lägga till or die.... [...]
Hur ska det hjälpa när filen är trunkerad och datan i minnet?
Har du någon koll på vad du snackar om?