Rilanci di Eccezioni e Problema con le Sessioni

Ciao a tutti, è il mio primo post ne approfitto per salutare i membri  . Vengo subito al dunque...

Sto studiando PHP/MySQL e arrivando al capitolo dell'eccezioni non ho capito bene a cosa serve rilanciarle una volta che magari sono state catturate da un blocco catch. Rilanciare un'eccezione in un blocco try/catch più interno serve per farla catturare da un blocco try/catch che contiene il precedente blocco? Se il suo funzionamento non è questo allora non ho ben capito....

Un'altro problema, che mi si presenta in locale, riguarda le sessioni. Uso windows xp pro con apache 2.2.9 e php 5.2.6 per sperimentare il php mentre lo studio. Per attivare le sessioni ho modificato a dovere il file php.ini, impostando session.save_path = "C:\Programmi\PHP\tmp". Mi sono scordato qualcosa? Chiedo questo perchè in locale le sessioni non mi funzionano!!! mentre su spazi web tipo altervista l'ho provate e funzionano (ho usato lo stesso esempio naturalmente).

Le sessioni le ho provate con questo file php:

<?php
            // le sessioni
            session_start();
            
            if(isset($_SESSION['counter'])) {
                $_SESSION['counter']++;
            } else {
                $_SESSION['counter'] = 1;
            }
            
            var_dump($_SESSION); echo("<br />");
            var_dump(session_id()); echo("<br />");
            var_dump(session_name()); echo("<br />");
            var_dump(session_get_cookie_params()); echo("<br />");
        ?>

Sullo spazio web, uploadata questa pagina php, tutte le volte che la si aggiorna la variabile counter si incremente fino a che non si chiude il browser.

In locale tutte le volte che aggiorno invece mi assegna sempre un id nuovo, infatti la cartella dove salvo le sessioni mi si riempie!!! mi si crea un file di sessione tutte le volte che refresho la pagine mentre il counter rimane a 1.

Forse manca qualcosa nel php.ini?

Grazie anticipatamente per le risposte!

Ciao!

PS: ho notato che anke i cookies, come le sessioni, non vengono memorizzati in locale... boh, sn disperato. Cmq ho visto con live http headers per FF che è proprio php o apache che non le invia.

inviato 8 anni fa
fedezzz
X 0 X

Normalmente i cicli try/catch servono proprio per rilanciare i programmi escludendo le eccezioni che ne hanno causato il blocco.

La cartella C:\.......PHP\TMP a chi appartiene? Ovvero gira con gli stessi privilegi del PHP o l'hai creata tu?

risposto 8 anni fa
Marco Grazia
X 0 X

Scusa ma sn duro non ho ben capito riguardo i cicli try/catch, cioè, se trovo una cosa del genere:

catch(Exception $e) {
  // scusa il codice, l'ho buttata un po li sul momento
   echo( $e->getMessage());

  // questa qui sotto che funzione ha?
  throw $e;
}

l'eccezione viene rilanciata alla funzione handler (che cmq si puo' modificare, se non sbaglio, attraverso un'altra funzione) o ad un blocco try piu esterno?

Per quanto riguarda l'altro problema ti posso dire che ho seguito le istruzioni di questo sito per configurare php/apache/mysql, e cmq prima di far partire apache ho creato la cartella C:/programmi/php/tmp . I privilegi cm faccio a vederli?

ciao grazie anticipatamente

risposto 8 anni fa
fedezzz
X 0 X

Ora sono senza manuale, però throw (in inglese: gettare in senso figurato) serve a risolvere l'errore, se non ricordo male.

Mentre per l'altro problema intendevo chiedere se l'utente sotto cui ggira il PHP è amministratore, guest o cos'altro e se la cartella non l'hai creata tu come altro utente, insomma guarda che errori ti da.

risposto 8 anni fa
Marco Grazia
X 0 X

Si PHP/apache/mysql gli faccio girare sotto privilegi di amministratore (loggo su win con il mio utente admin e gli faccio partire). Poi si la cartella anche questa l'ho creata con lo stesso account admin che uso di solito (loggo e lavoro sempre con quello). Per quanto riguarda gli errori non mi dice nulla neanke se gli abilito tutti nel php.ini

risposto 8 anni fa
fedezzz
X 0 X

Incredibile finalmente dopo 5 giorni di fusione celebrale sono arrivato alla soluzione del problema che riguarda i cookies e le sessioni!

La soluzione è stata questa (la scrivo cosi magari qualcuno che ha avuto lo stesso problema risolve)...

Prima il file di host di windows appariva cosi in sostanza:

127.0.0.1   localhost

io facevo puntare la document root di apache a C:/www e quando andavo su FF come url scrivevo http://localhost/ e mi portava alla visione web di quella dir dove poi andavo ad eseguire gli script che xò far funzionare sessioni e cookies non ne volevano sapere.

Cambiando il file host in cosi (aggiungendo una nuova riga)...

127.0.0.1   localhost
***.**.**.**    sitodifedezzz.com

faccio puntare sitodifedezzz.com all'ip interno della rete fastweb, che non è 127.0.0.1 (io ho fastweb, al posto dei numeri nell'ip interno della rete ho messo asterischi per la mia privacy).

allora quando poi provo a fare lo stesso procedimento di prima xò con l'url http://sitodifedezzz.com sessioni e cookies funzionano! ora finalmente posso andare avanti con lo studio. :)

Per quanto riguarda le eccezioni, se ho un file del genere (esempio del libro, ne scrivo solo una funzione della classe, basta quella):

[php]<?php

require_once('errors.inc');


class UserManager
{
  //
  // verifies that this user name doesn't have any invalid
  // characters in it.  please see Chapter 17: "Data
  // Validation with Regular Expressions" for a discussion
  // of the ereg function.
  //
  public function isValidUserName($in_user_name)
  {
    if ($in_user_name == ''
        or ereg('[^[:alnum:] _-]', $in_user_name) === TRUE)
      return FALSE;
    else
      return TRUE;
  }

  //
  // - get connection
  // - make sure the user name does not already exist.
  // - add record to users table.
  //
  public function createAccount
  (
    $in_uname,
    $in_pw,
    $in_fname,
    $in_email,
    $in_year,
    $in_month,
    $in_day
  )
  {
    //
    // 0. quick input validation
    //
    if ($in_pw == '' or $in_fname == ''
        or !$this->isValidUserName($in_uname))
    {
      throw new InvalidArgumentException();
    }

    //
    // 1. get a database connection with which to work.
    //    throws on failure.
    //
    $conn = $this->getConnection();

    try
    {
      //
      // 2. make sure user name doesn't already exist.
      //
      $exists = FALSE;
      $exists = $this->userNameExists($in_uname, $in_conn);
      if ($exists === TRUE)
        throw new UserAlreadyExistsException();

      //
      // 3a. make sure the parameters are safe for insertion
      //      and encrypt the password for storage.
      //
      $uname = $this->super_escape_string($in_uname, $conn);
      $fname = $this->super_escape_string($in_fname, $conn);
      $email = $this->super_escape_string($in_email, $conn);
      $pw = md5($in_pw);

      //
      // 3b. create query to insert new user.
      //
      $qstr = <<<EOQUERY
INSERT INTO Users
      (user_name,password,full_name,user_email,birthdate)
     VALUES ('$uname', '$pw', '$fname', '$email',
             '$in_year-$in_month-$in_day')
EOQUERY;

      //
      // 3c. insert new user
      //
      $results = @$conn->query($qstr);
      if ($results === FALSE)
        throw new DatabaseErrorException($conn->error);

      //
      // we want to return the newly created user id.
      //
      $user_id = $conn->insert_id;
    }
    catch (Exception $e)
    {
      if (isset($conn))
        $conn->close();
      throw $e;
    }

    //
    // clean up and exit
    //
    $conn->close();
    return $user_id;
  }
//... il file poi va avanti...[/php]

errors.inc invece è cosi:

[php]<?php

class InvalidArgumentException extends Exception
{
  public function __construct()
  {
    parent::__construct('The function was called with an invalid parameter');
  }
}

class UserAlreadyExistsException extends Exception
{
  public function __construct()
  {
    parent::__construct('A user with the given name already exists.');
  }
}

class DatabaseErrorException extends Exception
{
  public function __construct($in_msg)
  {
    parent::__construct('A database error occurred: '
                        . $in_msg);
  }
}[/php]

Nella funzione createAccount c'è un blocco catch, una volta che sono lanciate delle eccezioni tipo DatabaseErrorException il programma va a finire qui:

[php]catch (Exception $e)
    {
      if (isset($conn))
        $conn->close();
      throw $e;
    }[/php]

no?

ecco quel throw $e; dove rimanda?

Grazie anticipatamente, ciao! :)

risposto 8 anni fa
fedezzz
X 0 X

All'errore :)

$e è una classe di oggetti i cui membri li trovi in error.inc dove la classe predefinita exceptions() viene estesa.

In poche parole throw $e non fa altro che richiamare il giusto membro della classe estesa, che mostra o dovrebbe mostrare, il tipo di errore che è avvenuto.

Tornando al file host il tuo metodo funziona evvero ma è sbagliato usare host perché poni il tuo PC a rischio di intrusioni.

Host non andrebbe mai abilitato, ma usati gli host virtuali di Apache, ho rivisto un po' ciò che hai scritto e se fossi in te mi andrei a guardare se l'httpd.conf è scritto bene.

Ps ma chi ha scritto quegli esempi? Sono scritti in un modo pazzesco.

risposto 8 anni fa
Marco Grazia
X 0 X

Grazie ora per le eccezioni è 1 po più chiaro :)

Per il file host si hai ragione xò se in qualche modo non faccio puntare apache al mio indirizzo interno della rete addio sessioni e addio cookies. Forse posso eliminare la voce nel file di host di windows e in qualche modo far puntare un host virtuale di apache al mio indirizzo interno. Che ne dici?

Perchè dici esempi sn scritti in modo paccesco? in senso buono o in senso caotico? ;D Sono del libro "Core Web Application Development With Php And Mysql"

Ciao e grazie 1000  ;D

risposto 8 anni fa
fedezzz
X 0 X

Ho provato con i virtual host ma niente (avevo già provato una settimana fa) . Ecco ma se con il mio firewall bloccassi gli accessi da tutti gli IP della stessa rete al mio computer (o ad apache + specificatamente) tranne che per il mio IP di rete? Non potrebbe essere una soluzione? davvero, io se non uso il mio ip di rete non riesco a farli funzionare, ho smanettato giorni sulle configurazioni di apache.

risposto 8 anni fa
fedezzz
X 0 X

Scusa un attimo, apache immagino sia settato da httpd.conf per usare l'IP 127.0.0.1 sulla porta 80 immagino.

A questo punto mica devi dire a nessuno (host file) che 127.0.0.1 appartiene a localhost.

Quindi in httpd.conf devono esserci:

Listen 127.0.0.1:80

ServerName localhost:80

Poi nel php.ini

[Session]

session.save_handler = files

session.save_path = "C:\path\alla\cartella\tmp"

session.use_cookies = 1

; This option enables administrators to make their users invulnerable to

; attacks which involve passing session ids in URLs; defaults to 0.

; session.use_only_cookies = 1

; Name of the session (used as cookie name).

session.name = PHPSESSID

; Initialize session on request startup.

session.auto_start = 0

; Lifetime in seconds of cookie or, if 0, until browser is restarted.

session.cookie_lifetime = 0

; The path for which the cookie is valid.

session.cookie_path = /

; The domain for which the cookie is valid.

session.cookie_domain =

; Handler used to serialize data.  php is the standard serializer of PHP.

session.serialize_handler = php

; Define the probability that the 'garbage collection' process is started

; on every session initialization.

; The probability is calculated by using gc_probability/gc_divisor,

; e.g. 1/100 means there is a 1% chance that the GC process starts

; on each request.

session.gc_probability = 1

session.gc_divisor     = 100

; After this number of seconds, stored data will be seen as 'garbage' and

; cleaned up by the garbage collection process.

session.gc_maxlifetime = 1440

; NOTE: If you are using the subdirectory option for storing session files

;       (see session.save_path above), then garbage collection does *not*

;       happen automatically.  You will need to do your own garbage

;       collection through a shell script, cron entry, or some other method.

;       For example, the following script would is the equivalent of

;       setting session.gc_maxlifetime to 1440 (1440 seconds = 24 minutes):

;          cd /path/to/sessions; find -cmin +24 | xargs rm

; PHP 4.2 and less have an undocumented feature/bug that allows you to

; to initialize a session variable in the global scope, albeit register_globals

; is disabled.  PHP 4.3 and later will warn you, if this feature is used.

; You can disable the feature and the warning separately. At this time,

; the warning is only displayed, if bug_compat_42 is enabled.

session.bug_compat_42 = 1

session.bug_compat_warn = 1

; Check HTTP Referer to invalidate externally stored URLs containing ids.

; HTTP_REFERER has to contain this substring for the session to be

; considered as valid.

session.referer_check =

; How many bytes to read from the file.

session.entropy_length = 0

; Specified here to create the session id.

session.entropy_file =

;session.entropy_length = 16

;session.entropy_file = /dev/urandom

; Set to {nocache,private,public,} to determine HTTP caching aspects

; or leave this empty to avoid sending anti-caching headers.

session.cache_limiter = nocache

; Document expires after n minutes.

session.cache_expire = 180

; trans sid support is disabled by default.

; Use of trans sid may risk your users security.

; Use this option with caution.

; - User may send URL contains active session ID

;   to other person via. email/irc/etc.

; - URL that contains active session ID may be stored

;   in publically accessible computer.

; - User may access your site with the same session ID

;   always using URL stored in browser's history or bookmarks.

session.use_trans_sid = 0

; Select a hash function

; 0: MD5   (128 bits)

; 1: SHA-1 (160 bits)

session.hash_function = 0

; Define how many bits are stored in each character when converting

; the binary hash data to something readable.

;

; 4 bits: 0-9, a-f

; 5 bits: 0-9, a-v

; 6 bits: 0-9, a-z, A-Z, "-", ","

session.hash_bits_per_character = 4

; The URL rewriter will look for URLs in a defined set of HTML tags.

; form/fieldset are special; if you include them here, the rewriter will

; add a hidden <input> field with the info which is otherwise appended

; to URLs.  If you want XHTML conformity, remove the form entry.

; Note that all valid entries require a "=", even if no value follows.

url_rewriter.tags = "a=href,area=href,frame=src,input=src,form=,fieldset="

questo il mio php.ini che funziona

Perché gli esempi sono scritti male?

In realtà sono scritti bene ma usa una notazione che non mi piace perché porta confusione, ad esempio i nomi di variabili passate su una funzione devono sempre essere messi su un unico rigo e non andare a capo, se no non si capisce più cosa siano.

Ovviamente è solo un tipo di notifica, ma a me non piace perché mi confonde.

risposto 8 anni fa
Marco Grazia
X 0 X

si cosi c'avevo già provato all'inizio.. non mi funziona. potrebbe essere un problema riguardante il fatto che faccio parte della rete fastweb? oppure firewall? ho zone alarm...

risposto 8 anni fa
fedezzz
X 0 X

Non penso che c'entri Fastweb, più probabile quella zozzeria di Zone alarm, prova a cercare in esso se per caso ha bloccato l'esecuzione di qualche programma del tuo server Apache e/o PHP, ma dubito che sia così semplice.

risposto 8 anni fa
Marco Grazia
X 0 X

mah nn so che dire, non sono un esperto di sicurezza e firewall xò ho controllato  :) probabilmente sarà quelllo... boh.

Te la posso fare una domanda? te hai detto che il mio pc per via del file host modificato per apache è a rischio intrusioni.... in che modo? cioè da quello che so io il file host serve solo per "bindare" un nome ad 1 ip (almeno io so cosi).

ciao grazie ;)

risposto 8 anni fa
fedezzz
X 0 X

Per prima cosa come moderatore devo invitare fedezzz ad affrontare un solo problema per discussione.

Tornando alla questione sulle eccezione. Il rilancio delle eccezioni è una piuttosto diffusa quando l'applicativo definisce diversi tipi di eccezioni ed in alcuni casi è necessario convertire un tipo di eccezione in un altro tipo.

Ad esempio supponiamo di aver definito una eccezione di tipo ApplicazionException. L'applicativo prova a generare la pagina richiesta dall'utente e fa un try - catch perché si aspetta una possibile ApplicazionException contenente il messaggio di errore da mostrare all'utente.

Supponiamo d utilizzare una classe per la connessione al database che genera una SqlException se una query non va a buon fine. Questa eccezione conterrà diverse informazioni sullerrore avvenuto: codice errore di MySQL, descrizione errore di MySQL, query eseguita, ecc.

Con la tecnica del rilancio delle eccezioni possiamo intercettare le SqlException, registrare le informazioni in esse contenute su un file di log e lanciare una ApplicationException per infomare l'utente del problema.

A volte si può voler intercettare un tipo di eccezione, eseguire determinate operazioni e poi rilanciare la stessa eccezione. Ad esempio intercettiamo la SqlException, memorizziamo le informazioni in essa contenute nelk file di log, chiudiamo la connessione al database ed infine la rilanciamo, poiché vogliamo lasciare a qualche altro componente dell'applicativo il compito di catturarla per mostrare un messaggio di errore all'utente.

 :bye:

risposto 8 anni fa
Gianni Tomasicchio
X 0 X

mmmh sempre meglio riguardo le eccezioni, grazie per le delucidazioni. :) cmq si forse sono andato un po off topic, chiedo scusa, caso mai o aprirò un'altro topic oppure vedrò di informarmi da me.

grazie a tutti, ciao alla prossima ;)

risposto 8 anni fa
fedezzz
X 0 X

Un dubbio?!  :-\

Parlando ancora di eccezioni...

Se abbiamo appunto detto che un'eccezione, per poter essere lanciata, abbisogna di un blocco try-catch,

com'è che posso farlo se, nel codice riportato da fedezzz, viene lanciata un'eccezione senza inserire un riferimento all'interno di "try".

Ecco l'esempio:

//

    // 0. quick input validation

    //

    if ($in_pw == '' or $in_fname == ''

        or !$this->isValidUserName($in_uname))

    {

      throw new InvalidArgumentException();

    }

Se osservate il codice riportato da fedezzz, (quello completo) non vi è un controllo all'interno di try.

Anch'io ho acquistato lo stesso manuale e ho provato a testare l'esempio, ma mi esce in continuazione il Fatal Error: Uncaught Exception!

Perchè?

Grazie..

Luka   ;)

risposto 8 anni fa
Luca
Luca
1
modificato 8 anni fa
X 0 X

Il blocco try-catch serve a bloccare una eccezione, a fermarne la risalita verso le funzioni ed i metodi chiamanti.

Il blocco try-catch può essere usato per ri-lanciare una eccezione.

Se una eccezione non viene bloccata da alcun blocco try-catch allora si riceve l'errore "Fatal Error: Uncaught Exception!"

 :bye:

risposto 8 anni fa
Gianni Tomasicchio
X 0 X

corretto!

Ma in effetti nel codice riportato da fedezzz l'eccezione non viene bloccata!

Puoi dar un'occhiata?!

Grazie..

Luka  ;)

risposto 8 anni fa
Luca
Luca
1
X 0 X

Ok, tento di spiegarmi riportando il codice dei singoli files, perchè temo che il problema dipenda dalla chiamata alle eccezioni:

file "process.php": (è richiamato dopo aver cliccato nel pulsante "submit" della mia form)

<?php

require_once('user_manager.inc');


$in_uname = $_POST['nome'];

$usermgr = new UserManager();
$usermgr->TestInput($in_uname);

?>

file "user_manager.inc" : (richiamato dal file "process.php")

<?php

require_once('errore.inc');

class UserManager
{

   public function TestInput($nome)
   {
      $parolacce = "scemo";
      try
      {
         if($nome == NULL)
            throw new InputInvalido();
            
         if($nome == $parolacce)
            throw new ExplicitInput();
      }
      catch (Exception $e)
      {
         throw $e;
      }
   }
}
?>

ed infine, file "errore.inc" : (incluso in "user_manager.inc")

<?php

class InputInvalido extends Exception
{
   public function __contruct()
   {
      parent::__construct('Il valore inserito non è corretto!');
   }
}

class ExplicitInput extends Exception
{
   public function __contruct()
   {
      parent::__construct('La parola inserita contiene contenuto esplicito!');
   }
}
   
?>

Ora, perchè mi appare sempre il fatal error, "Uncaught Exception", nonostante il blocco try-catch sia stato correttamente impostato???

Spero mi aiuterete a far luce..

Grazie!

Luka   ;)

risposto 8 anni fa
Luca
Luca
1
modificato 8 anni fa
X 0 X

catch (Exception $e)

{

     throw $e;

}

con questo codice blocchi l'eccezione (catch (Exception $e)) e poi la rilanci (throw $e;)

in pratica non fai nulla  :dunno:

risposto 8 anni fa
Gianni Tomasicchio
X 0 X

Si, ma nel libro riportavano questo metodo!   :tichedoff:

Quindi, allora, cosa dovrei scrivere?

Grazie Gianni..

Luka   ;)

risposto 8 anni fa
Luca
Luca
1
X 0 X

Si, ma nel libro riportavano questo metodo!   :tichedoff:

Quindi, allora, cosa dovrei scrivere?

Grazie Gianni..

Luka   ;)

dipende da cosa vuoi ottenere...  :bye:

risposto 8 anni fa
Gianni Tomasicchio
X 0 X

...semplicemente catturare l'eccezione e far apparire il messaggio di errore relativo!

Grz.

 ;)

risposto 8 anni fa
Luca
Luca
1
X 0 X

allora invece di lanciare "throw $e; " metti nel blocco catch delle istruzioni per stampare un messaggio

 :bye:

risposto 8 anni fa
Gianni Tomasicchio
X 0 X

si, ma come puoi vedere nel codice che ho riportato ("errore.inc") i messaggi variano in base all'errore!

Quindi, ho bisogno di richiamare con un unico "catch" il messaggio relativo!

Come si fa?

Grazie

Luka

 ;)

risposto 8 anni fa
Luca
Luca
1
X 0 X

per gestire in maniera differenziata i diversi tipi di eccezione devi realizzare più blocchi catch:

try {
   // ...
} catch (InputInvalido $ii) {
   // ...
} catch (ExplicitInput $ei) {
   // ...
}

 :bye:

risposto 8 anni fa
Gianni Tomasicchio
X 0 X

Già,Già! Lo intuivo...   :)

Bhè, allora gestirò in questo modo!

Ascolta, che ne pensi della "vecchia scuola"?

(ovvero vecchio sistema di creare applicazioni senza la programmazione ad oggetti?)

Grz!

Luka   ;)

I LOVE PHP  :buck:

risposto 8 anni fa
Luca
Luca
1
X 0 X

Rischiamo di andare OT, comunque ritengo che per applicazioni PHP medio grandi la programmazione ad oggetti sia doverosa

 :bye:

risposto 8 anni fa
Gianni Tomasicchio
X 0 X

Ottimo! Grazie dell'opinione!!

Luka

 ;)

risposto 8 anni fa
Luca
Luca
1
X 0 X
Effettua l'accesso o registrati per rispondere a questa domanda