PDA

View Full Version : [PHP] Struct come nel C,c'è un modo?


Roran
10-04-2010, 13:36
c'è un modo per creare delle struct come quelle del C in php?intendo delle struct come quelle utilizzate per le liste,in questo modo:

struct nodo {
int val;
struct nodo *next;
}

DanieleC88
10-04-2010, 15:32
Una classe?

Roran
10-04-2010, 16:46
come il java quindi?Chiedo perchè il php ad oggetti non l'ho mai provato

DanieleC88
10-04-2010, 16:47
Io propenderei per una classe (anche perché non mi risulta che esistano strutture in PHP). Vai tranquillo, la sintassi delle classi di PHP è vagamente simile a Java, quindi non dovresti avere enormi difficoltà.

cionci
10-04-2010, 18:20
Un vettore associativo magari è più simile:

nodo['val'] = 0
nodo['next'] = &altronodo;

DanieleC88
10-04-2010, 18:23
Oddio è un po' bruttino scomodare una hashmap per implementare una lista... :D

cionci
10-04-2010, 18:29
Le struct quando il php non aveva le classi si realizzavano così ;)

DanieleC88
10-04-2010, 18:31
Uno dei motivi per cui preferisco Python. :p

cionci
10-04-2010, 18:35
Uno dei motivi per cui preferisco Python. :p
Vorrei anche vedere. PHP è uno dei linguaggi più brutti della storia, però bisogna dire che a volte è veramente comodo.

DanieleC88
10-04-2010, 18:37
Esatto, PHP per certe cose è una specie di abominio, ma è letteralmente ovunque...

cionci
10-04-2010, 18:39
Comunque la lista in php non si fa, è semplice...

Si fa un array, poi si usa array_push e array_pop. Se bisogna cercare un elemento si fa una ricerca direttamente.

Roran
10-04-2010, 20:12
Comunque la lista in php non si fa, è semplice...

Si fa un array, poi si usa array_push e array_pop. Se bisogna cercare un elemento si fa una ricerca direttamente.esistono gia queste due funzioni?si può fare su un array associativo?

cionci
10-04-2010, 20:37
esistono gia queste due funzioni?si può fare su un array associativo?
Certo che esistono: http://www.php.net/manual/en/function.array.php
array_push, array_pop, array_shift, array_unshift non prendono la chiave, ma usano gli interi come chiave. Puoi comunque fare il push di un altro array associativo.
Tutti gli array sono associativi in PHP.

Roran
12-04-2010, 20:39
Per provare con un classe avevo provato in questo modo:
class commenti
{
public $nick;
public $comm;

function __construct($nickname,$commento){
$this->nick=$nickname;
$this->comm=$commento;
}
}// FINE CLASSE


//MAIN
$nomefile="commenti.txt";
$obj=new commenti('Roran','prova classe');
echo $obj->nick."<BR>".$obj->comm;
funziona però non ho risolto nulla,dato che devo implementare i metodi per creare una lista dinamica

Oggi invece ho provato in questo modo:
class Commento{
private $nickname;
private $commento;
private $next=new Commento();

function __construct($nickname,$commento,$n){
$this->nickname=$nickname;
$this->commento=$commento;
$this->next=$n;
}
}// FINE CLASSE COMMENTO
che ovviamente non funziona perchè mi da errore sulla riga dove dichiaro $next
per fare in questo modo mi sono basato sulla creazione di un nodo di una lista,scritto in java,come segue:
public class Commenti{
private static class Elem{
private String nickname;
private String commento;
private Elem next;

private Elem(String nick,String comm,Elem n){
nickname=nick;
commento=comm;
next=n;
}
}
}

come posso fare la stessa cosa modificando la parte in php che ho scritto sopra?

anonimizzato
12-04-2010, 20:51
Vorrei anche vedere. PHP è uno dei linguaggi più brutti della storia

:cry:

cionci
12-04-2010, 21:00
class Commento{
private $nickname;
private $commento;
private $next;

function __construct($nickname,$commento,$n){
$this->nickname=$nickname;
$this->commento=$commento;
$this->next=&$n;
}
}// FINE CLASSE COMMENTO

Come ti ho detto, non ha senso creare una lista in PHP, puoi benissmo usare un vettore di classi commento ed usare array_push per l'inserimento in coda e array_shift per la rimozione dalla testa.
Per scorrerti l'intera lista fai un semplice foreach e per cercare un elemento usi le varie funzioni per la ricerca.

Roran
12-04-2010, 21:09
class Commento{
private $nickname;
private $commento;
private $next;

function __construct($nickname,$commento,$n){
$this->nickname=$nickname;
$this->commento=$commento;
$this->next=&$n;
}
}// FINE CLASSE COMMENTO

Come ti ho detto, non ha senso creare una lista in PHP, puoi benissmo usare un vettore di classi commento ed usare array_push per l'inserimento in coda e array_shift per la rimozione dalla testa.
Per scorrerti l'intera lista fai un semplice foreach e per cercare un elemento usi le varie funzioni per la ricerca.mmm ecco,forse ora ho capito meglio,quindi posso tranquillamente togliere i campi next nella classe e poi faccio un vettore della classe commento?

edit: però se volessi cancellare un commento che sta in mezzo al vettore?la pop che io sappia non va bene,o mi sbaglio?

cionci
12-04-2010, 21:14
edit: però se volessi cancellare un commento che sta in mezzo al vettore?la pop che io sappia non va bene,o mi sbaglio?
http://www.php.net/manual/en/function.array-search.php
Guardatelo l'help ;)

Roran
12-04-2010, 21:20
http://www.php.net/manual/en/function.array-search.php
Guardatelo l'help ;)
grazie del link,domani lo guardo con calma

cionci
12-04-2010, 21:21
Se vuoi eliminare un elemento usa unset(v[x]);
Se vuoi inserire un elemento ad un dato indice usa array_splice.

Roran
13-04-2010, 20:42
Se vuoi eliminare un elemento usa unset(v[x]);
Se vuoi inserire un elemento ad un dato indice usa array_splice.ho provato push e pop ed è tutto chiaro,ho fatto l'array di oggetti è funge benissimo,ho solo un dubbio,facendo unset mi rimane l'indice vuoto?oppure avviene uno shift automatico?

cionci
14-04-2010, 09:29
Rimane l'indice vuoto. Per scorrere tutti gli elementi usa il foreach, gli elementi vuoti verranno saltati.

Roran
14-04-2010, 14:59
<?php

class commenti
{
public $nick;
public $comm;

function __construct($nickname,$commento){
$this->nick=$nickname;
$this->comm=$commento;
}
}// FINE CLASSE


//MAIN
$nomefile="commenti.txt";
$listacommenti = array();
$listacommenti=carica($nomefile);
$length=conta_commenti($listacommenti);
echo "<BR>".$length;


//inserimento commenti
function inserisci_commento(&$listacommenti,$nickname,$commento){
$obj=new commenti($nickname,$commento);
array_push($listacommenti, $obj);
}

//conta commenti
function conta_commenti(&$listacommenti){
return(count($listacommenti));
}

// carica commenti da file
function carica($nomefile,&$listacommenti){
$flag=true;
$insert=false;
$nick='';
$comm='';
if (!$p_file = fopen($nomefile,"r")) {
echo "Spiacente, non posso aprire il file";
} else {
while(!feof($p_file)) {
$carattere = fread($p_file,1);
if($carattere=='|') $flag=false;
if($flag==true && $carattere!='|') $nick=$nick.$carattere;
else if($flag==false && $carattere!='\n') $comm=$comm.$carattere;
if($carattere=='\n') {
$flag=true;
$insert=true;
}
if($insert==true) {
inserisci_commento($listacommenti,$nick,$comm);
$insert=false;
}
}
//echo $listacommenti[0]->nick;
fclose($p_file);
}
}


?>

Eccomi di nuovo a chiedere aiuto,premetto che ho provato sia la funzione inserisci_commento(&$listacommenti,$nickname,$commento) che la funz. conta_commenti(&$listacommenti) in modo diretto e funzionano entrambe.Ora ho un nuovo problema,ho scritto la fuzione carica($nomefile,&$listacommenti) però è come se saltasse la chiamata a inserisci_commento perchè quando visualizzo la variabile length che contiene il numero di elementi dell'array,mi visualizza 0,lo stesso se tolgo // dall'ultima riga commentata,mi da un errore dicendomi che non trova l'oggetto.Nel file da quale leggo ho scritto solo
nome|commento

dopo il commento vado a capo riga.

cionci
14-04-2010, 16:00
Da

$listacommenti=carica($nomefile);

a

carica($nomefile, $listacommenti);


Per caricare i commenti:

$file = file($nomefile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
foreach($file as $line)
{
$splited = preg_split("/[|]/", $line, -1, PREG_SPLIT_NO_EMPTY);
if(count($splitted) != 2)
continue; //ignore malformed lines
inserisci_commento($listacommenti, $splitted[0], $splitted[1]);
}

Roran
14-04-2010, 21:26
Da

$listacommenti=carica($nomefile);

a

carica($nomefile, $listacommenti);


Per caricare i commenti:

$file = file($nomefile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
foreach($file as $line)
{
$splited = preg_split("/[|]/", $line, -1, PREG_SPLIT_NO_EMPTY);
if(count($splitted) != 2)
continue; //ignore malformed lines
inserisci_commento($listacommenti, $splitted[0], $splitted[1]);
}
Grazie per la funzione,veramente utile,solo che c'è un piccolo problemino.riguarda la scrittura su file,quando finisco di scrivere il commento faccio anche fwrite($nomefile, '\n'); solo che il nick dopo viene scritto attaccatto alla fine del commento prima,con la funzione di lettura che avevo scritto io andava,non so come faceva a riconoscere il carattere però funzionava,c'è un modo proprio per scrive a capo riga?

cmq la parte in grassetto e stato un errore di copia incolla,avevo rivoluzionato la funzione del caricamento provando con un array che veniva restituito,poi mi sono dimenticato di rimettere tutto come stava

cionci
14-04-2010, 21:31
Non vedi alcun fwrite nel codice....

Roran
14-04-2010, 22:29
Non vedi alcun fwrite nel codice....lo avevo postato nell' altro thread,cmq dicevo in generale,lo so che nel codice postato qui non c'è,non c'è proprio la funzione di scrittura ;)

cmq eccolo:
<html>
<body>
<?php
include("leggi_commenti.php");
session_start();
$nomefile="commenti.txt";
$nick=$_GET['nick'];
$commento=$_GET['commenti'];
$code=$_GET['code'];
$postID=npost($nomefile);
//controllo antispam
if($_SESSION['antispam'] ==$code) scrittura($nomefile,$nick,$commento,$postID);
else{
echo "<SCRIPT>alert('Controlla che il codice inserito corrisponda a quello visualizzato');";
echo "history.back();</SCRIPT>";
}

//scrittura sul file
function scrittura($nomefile,$nick,$commento,$postID){
if(($nick!="") && ($nick!="il tuo nickname")){
if(($commento!="") && ($commento!="Scrivi qui il testo")){
$postID++;
$p_file = fopen($nomefile,"a");
if(!$p_file) die("impossibile lasciare un commento,contattare l'amministratore");
$scrivicommento = fwrite($p_file,"[".$postID."] "); //contatore post
$scrivicommento = fwrite($p_file,"<b>".$nick."</b>"."\n");
$scrivicommento = fwrite($p_file,"«".$commento."»");
fclose($p_file);
}
else {
echo "<SCRIPT>alert('Il testo digitato è troppo breve o non valido');";
echo "history.back();</SCRIPT>";
}
}
else {
echo"<SCRIPT>alert('Devi immettere un Nickname valido');";
echo "history.back();</SCRIPT>";
}
}
?>
<script language="JavaScript" type="text/javascript">
location.href=('http://localhost/prova.php');
</script>
</body>
</html>
questa è la vecchia funzione,di quando non utilizzavo una classe,l'ho postata per far vedere fwrite

Roran
15-04-2010, 21:04
ho risolto mettendo \r prima di \n,ora funziona come deve

Roran
15-04-2010, 21:40
diciamo che ora ho quasi finito,devo solo far funzionare la funzione per cancellare un commento dal file di testo,solo che mi cancella tutto il file,ecco la funzione:

//cancella commento
function cancella($nomefile,&$listacommenti,$nick){
$file = file($nomefile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
$f=fopen($nomefile,"w");
foreach($file as $line)
{
$splitted = preg_split("/[|]/", $line, -1, PREG_SPLIT_NO_EMPTY);
if(count($splitted) != 2)
continue; //ignore malformed lines
if($splitted[0]== $nick) fputs($f,$line);
}
fclose($f);
}$nick l'ho messo li solo per provare,gliene passo uno tanto per provare

cionci
15-04-2010, 21:51
Forse: if($splitted[0] != $nick)

Hal2001
15-04-2010, 21:55
Io rimango sconvolto ogni volta che leggo questa sezione.
C'è gente che ha una cultura infinita, mastica C, Java, Python, PHP, e conosce anche altro!
Ma come fate? :)

Roran
15-04-2010, 22:24
Forse: if($splitted[0] != $nick)mettendo != cancellerebbe tutte le righe che non iniziano con quel nick,però comunque il problema penso sia un altro,perchè invece di cancellare una sola riga mi cancella tutto il file di testo


Io rimango sconvolto ogni volta che leggo questa sezione.
C'è gente che ha una cultura infinita, mastica C, Java, Python, PHP, e conosce anche altro!
Ma come fate? :)bhe io personalmente conosco bene C e C++ perchè li ho utilizzati per 3 anni alle superiori (dal terzo al quinto) e ho continuato ad usarli anche all'università nel primo semestre (sono al primo anno di informatica),ora sto imparando il java e me la cavo abbastanza bene.Alle superiori ho fatto anche un pò di php insieme al MY SQL.

cionci
16-04-2010, 01:21
mettendo != cancellerebbe tutte le righe che non iniziano con quel nick,però comunque il problema penso sia un altro,perchè invece di cancellare una sola riga mi cancella tutto il file di testo
E' normale, tu stai scrivendo un nuovo file da zero. Per questo devi scrivere sul file tutte le righe escluse quelle che non vuoi (come in C tra l'altro, fopen funziona allo stesso modo).

Roran
16-04-2010, 21:15
E' normale, tu stai scrivendo un nuovo file da zero. Per questo devi scrivere sul file tutte le righe escluse quelle che non vuoi (come in C tra l'altro, fopen funziona allo stesso modo).mi cancella tutto il file anche con !=