Pagina 1 di 3 1 2 3 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 28
  1. #1

    [cli] accesso alla tastiera

    Sto utilizzando PHP da riga di comando, che per certi versi trovo più rapido del C. Un baco che però mi limita molto è l'input da tastiera, veramente ridicolo, tramite

    $s = fgets(STDIN, 128);

    In cui l'esecuzione del programma si stoppa bruscamente e non riparte finchè l'utente non ha premuto INVIO. Ora io vorrei fare dei cicli nel frattempo e farli terminare quando l'utente preme ESC, ma non è possibile al momento.

    Conoscete qualche metodo per intercettare qualche segnale da tastiera che non sia fges() ?
    Concentrate on what cannot lie... The evidence. -- Gil Grissom

  2. #2
    Utente di HTML.it L'avatar di xPilux
    Registrato dal
    Jul 2004
    Messaggi
    103
    In tutti i linguaggi di programmazione si ferma l'esecuzione quando si aspetta un input...a meno che non si usino i thread...

  3. #3
    Ciao,
    non è un baco, la funzione fgets si interrompe quando incontra un \n (newline).

    Per fare quel che vuoi tu devi usare

    fread() e controllare ogni singolo carattere fino a quando non trovi il tuo carattere di "termine scrittura", oppure qualcosa del tipo

    [pseudocodice]

    $testoTotale = '' ;

    while( $x = fgets(STDIN, $len))
    {

    //se $x contiene carattere da intercettare, fai break
    //altrimenti

    $testoTotale .= $x

    }

    Se la pressione sul tasto ESC invia un carattere testuale che sei in grado di intercettare puoi risolvere così.

    Per intercettare ESC credo tu debba fare un confronto con il valore restituito da chr(27), ma non ho mai provato
    per favore NIENTE PVT TECNICI da sconosciuti

  4. #4
    Originariamente inviato da xPilux
    In tutti i linguaggi di programmazione si ferma l'esecuzione quando si aspetta un input...a meno che non si usino i thread...
    Non è detto, come con le DirectX in cui l'input viene messo in un buffer (beh odio suppongo lo faccia un thread) e io posso svuotarlo leggendolo quando mi pare, l'esecuzione del programma non si blocca.

    Fabio nel tuo esempio l'esecuzione mi si stoppa su

    while($x = fgets(STDIN, $len))

    e non voglio che accada... se ho ben capito il tuo esempio.

    Ho letto che sarebbe possibile farlo con l'estensione NCURSES, ma, udite udite, non esiste per Windows... c'è per tutti gli OS più assurdi AIX, BeOS, Cygwin, Digital Unix (aka OSF1), FreeBSD, GNU/Linux, HPUX, IRIX, OS/2,
    SCO OpenServer, Solaris, SunOS e non per Win... (bestemmione)

    Io voglio creare una routine che fa i suoi controlli, sui file, sui socket, ma al contempo l'utente può interagire... PHP tramite CLI è molto potente e comodo, ma questa mancanza gli tronca parecchio le gambe.

    Aspetta, mentre scrivo mi è balenata un'idea di come poter fare, anche se è un' esagerazione. Creare lo script che voglio mandare in esecuzione all'infinto while(1) { ... } come server in ascolto su un socket e interagire tramite un client che si connette, ecco cazzo (scusate) così dovrebbe funzionare perchè il server non si stoppa sul controllo del socket tramite la socket_select()

    Però che palle...
    Concentrate on what cannot lie... The evidence. -- Gil Grissom

  5. #5
    Originariamente inviato da Frankesk

    Fabio nel tuo esempio l'esecuzione mi si stoppa su

    while($x = fgets(STDIN, $len))
    Si può fare in tanti modi, uno può essere questo


    $len = 4096 ;
    $stopChar = ... ;
    $buffer = '' ;

    while( false !== ($x = fgetc(STDIN)) )
    {

    if( $x == $stopChar )
    {
    break ;
    }

    else
    {

    $buffer .= $x ;

    }

    }

    Questo dovrebbe essere un ciclo infinito che si interrompe solo quando incontra $stopChar o ctrl+d.

    Un risultato simile puoi ottenerlo con fread(), fgets() etc.etc.


    Io voglio creare una routine che fa i suoi controlli, sui file, sui socket, ma al contempo l'utente può interagire... PHP tramite CLI è molto potente e comodo, ma questa mancanza gli tronca parecchio le gambe.
    Non è una mancanza, è che CLI lavora a basso livello quindi il buffer lo devi creare e gestire tu
    per favore NIENTE PVT TECNICI da sconosciuti

  6. #6
    Originariamente inviato da Fabio Heller
    Non è una mancanza, è che CLI lavora a basso livello quindi il buffer lo devi creare e gestire tu
    E' quello che vorrei! Leggermi il buffer come e quando voglio io, senza che l'esecuzioni si arresti su fgetc()!

    Il tuo esempio modificato per far vedere quello che vorrei fare:

    codice:
    $len = 4096 ; 
    $stopChar = 'c'; // per uscire dal ciclo
    $buffer = '' ; 
    
    $i = 0;
    while( false !== ($x = fgetc(STDIN)) ) 
    { 
    	// voglio che sia stamapto $i a intervalli di 1 secondo
    	// ...vorrei, ma non accade! perchè mi fermo su fgetc()
    	$i++;
    	fwrite(STDOUT, $i."\n");
    	sleep(1);
    
    	if( $x == $stopChar ) 
    	{ 
    		break; 
    	} 
    	else 
    	{ 
    		$buffer .= $x;
    	} 
    
    }
    
    fwrite(STDOUT, "quit command received.\n");
    sleep(2);
    A me serve una

    bool getKeyState($keycode);

    da poter controllare tranquillamente come:

    if(getKeyState(KEY_ESC)) break;

    ...e al momento non si può fare in PHP CLI, non c'è verso.

    Al momento ho "fixato" con quello stratagemma del server/client inserendo una cosa diquesto tipo:

    codice:
    $ss = new csmallserver();
    $ss->bind($this->address_sv, (int)$this->port_sv);
    $ss->listen();
    
    while(1)
    {
    	// fai fuffa, controlli, etc
    
    
    	// controllo se è giunto qualcosa al server
    	// $ss->poll() non si stoppa come fgetc() in attesa di INVIO
    	// o altro
    	$remote_command = $ss->poll();
    	if($remote_command != "")
    	{
    		if($remote_command == "quit")
    		{
    			$ss->close();
    			break;
    		}
    	}
    }
    Così va, ma è come mobilitare l'esercito USA contro un albanese che ruba una banana dal fruttivendolo...
    Concentrate on what cannot lie... The evidence. -- Gil Grissom

  7. #7
    Rileggendo mi sono accorto che forse non ho capito...

    tu vuoi intercettare l'input da tastiera e nel frattempo fare anche altre cose, magari in background.

    PHP non supporta i threads, ma in realtà (nei sistemi Unix) puoi utilizzare fork per creare dei processi figli

    Qui trovi maggiori informazioni
    http://freephp.html.it/articoli/view...olo.asp?id=130
    per favore NIENTE PVT TECNICI da sconosciuti

  8. #8
    Sì esatto

    Purtroppo sto su Windows...
    Concentrate on what cannot lie... The evidence. -- Gil Grissom

  9. #9
    mmm in realtà non è nemmeno un problema...basta che le funzioni che scrivi le scrivi in modo ASINCRONO...(come la lettura dei dati da tastiera) e spari tutto in delle funzioni...

    nel ciclo controlli una variabile che specifica se il ciclo deve essere interrotto e cosi puoi gestire tutto in maniera asincrona ^^

    per evitare problemi nel codice ti consiglio l'uso massiccio di classi cosi tieni tutte le vars dentro le classi stesse

    ciauz
    The fastest Redis alternative ... cachegrand! https://github.com/danielealbano/cachegrand

  10. #10
    Originariamente inviato da daniele_dll
    mmm in realtà non è nemmeno un problema...basta che le funzioni che scrivi le scrivi in modo ASINCRONO...(come la lettura dei dati da tastiera) e spari tutto in delle funzioni...


    Noooo, non è un problema...

    Come si fa a fare tutto in modo asincrono se le fgetc()/fgets() sono sincrone??

    Quando il flusso di programma arriva ad una fgetc()/fgets() ESSO SI STOPPA e aspetta che l'utente prema INVIO... non posso fare null'altro in questo modo

    Ho risolo usando socket_select() perchè almeno quella per fortuna è asincrona e la fgetc() sta su un altro piccolo script client che avvio solo per inviare il comando di break.
    Concentrate on what cannot lie... The evidence. -- Gil Grissom

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.