Trattare con eacute e altri caratteri speciali utilizzando Oracle, PHP e oci8
-
23-09-2019 - |
Domanda
Ciao Sto cercando di memorizzare i nomi in un database Oracle e li prendere indietro utilizzando PHP e oci8.
Tuttavia, se inserisco il é
direttamente nel database Oracle e utilizzare oci8 a prenderlo di nuovo ho appena ricevuto un e
Devo codificare tutti i caratteri speciali (tra cui é
) in entità html (vale a dire: é
) prima di inserire nel database ... o mi sto perdendo qualcosa
Thx
UPDATE: Mar 1 alle 18:40
Trovato questa funzione: http://www.php.net/manual/en/ function.utf8-decode.php # 85034
function charset_decode_utf_8($string) {
if(@!ereg("[\200-\237]",$string) && @!ereg("[\241-\377]",$string)) {
return $string;
}
$string = preg_replace("/([\340-\357])([\200-\277])([\200-\277])/e","'&#'.((ord('\\1')-224)*4096 + (ord('\\2')-128)*64 + (ord('\\3')-128)).';'",$string);
$string = preg_replace("/([\300-\337])([\200-\277])/e","'&#'.((ord('\\1')-192)*64+(ord('\\2')-128)).';'",$string);
return $string;
}
sembra funzionare, anche se non so se la soluzione ottimale
UPDATE: 8 marzo alle 15:45
set di caratteri di Oracle è ISO-8859-1.
in PHP Ho aggiunto:
putenv("NLS_LANG=AMERICAN_AMERICA.WE8ISO8859P1");
per forzare la connessione oci8 di utilizzare tale set di caratteri.
Recupero della é
utilizzando oci8 da PHP ora funzionato! (Per varchars
, ma non CLOBs
dovuto fare utf8_encode
per estrarlo)
Allora ho provato il salvataggio dei dati di PHP per Oracle ... e doesnt work..somewhere lungo la strada da PHP a Oracle il é
diventa un ?
UPDATE: Mar 9 alle 14:47
Quindi, sempre più vicino.
Dopo aver aggiunto la variabile NLS_LANG, facendo inserti OCI8 diretti con opere é
.
Il problema è in realtà sul lato PHP.
Utilizzando quadro ExtJS, al momento della presentazione di un modulo di codifica utilizzando encodeURIComponent
.
Così é
viene inviato come %C3%A9
e poi ri-codificato in é
.
Tuttavia la sua lunghezza è ora 2 (strlen($my_sent_value) = 2)
e non 1.
E se in PHP provo: $ my_sent_value == é
= false
Credo che se sono in grado di ricodificare tutti questi personaggi in PHP di nuovo in lunghezze di dimensione in byte 1 e poi inserendoli in Oracle, dovrebbe funzionare.
Ancora nessuna fortuna se
UPDATE: Mar 10 alle 11:05
Continuo a pensare io sono così vicino (eppure così lontano).
putenv("NLS_LANG=AMERICAN_AMERICA.WE8ISO8859P9");
funziona molto sporadicly.
ho creato un piccolo script php per prova:
header('Content-Type: text/plain; charset=ISO-8859-1');
putenv("NLS_LANG=AMERICAN_AMERICA.WE8ISO8859P9");
$conn= oci_connect("user", "pass", "DB");
$stmt = oci_parse($conn, "UPDATE temp_tb SET string_field = '|é|'");
oci_execute($stmt, OCI_COMMIT_ON_SUCCESS);
Dopo aver eseguito una volta e loggin nel database Oracle direttamente vedo che STRING_FIELD è impostato su |¿|
. Ovviamente non quello che avevo imparato ad aspettarsi dalla mia esperienza precedente.
Tuttavia, se rinfresco la pagina PHP rapidamente due volte .... ha funzionato !!!
In Oracle ho visto correttamente |é|
.
Sembra che forse la variabile d'ambiente non viene impostata correttamente o inviato in tempo per la prima esecuzione dello script, ma è disponibile per la seconda esecuzione.
Il mio prossimo esperimento è quello di esportare la variabile nell'ambiente di PHP, però, ho bisogno di ripristinare Apache per questo ... quindi vedremo cosa succede, speriamo che funziona.
Soluzione 2
Questo è quello che ho finalmente finito per fare per risolvere questo problema:
Modificato il profilo del PHP daemon in esecuzione di avere:
NLS_LANG=AMERICAN_AMERICA.WE8ISO8859P1
In modo che la connessione oci8 utilizza ISO-8859-1.
Poi, nella mia configurazione di PHP impostare il tipo di contenuto predefinito ISO-8859-1:
default_charset = "iso-8859-1"
Quando sto inserendo nel una tabella Oracle tramite oci8 da PHP, che faccio:
utf8_decode($my_sent_value)
E quando la ricezione dei dati da Oracle, la stampa la variabile dovrebbe funzionare come:
echo $my_received_value
Tuttavia, quando l'invio di tali dati nel corso ajax ho dovuto usare:
utf8_encode($my_received_value)
Altri suggerimenti
presumo siete a conoscenza di questi fatti:
- Ci sono molti set di caratteri diversi: bisogna sceglierne uno e, ovviamente, sapere che uno si utilizza .
- Oracle è perfettamente in grado di memorizzare testo senza entità HTML (
é
). entità HTML sono utilizzati in, beh, HTML. Oracle non è un browser Web; -)
Si deve anche sapere che HTML entità non si legano a un set di caratteri specifico; al contrario, sono utilizzati per rappresentare i caratteri in un contesto charset-indipendente.
È indistintamente parla di ISO-8859-1 e UTF-8. Che charset vuoi usare? ISO-8859-1 è facile da usare, ma si può solo testo negozio in alcune lingue latine (come lo spagnolo) e manca alcuni caratteri comuni come il simbolo €. UTF-8 è più complicato da usare, ma in grado di memorizzare tutti i caratteri definiti dal consorzio Unicode (che includono tutto ciò di cui avrete bisogno).
Una volta che hai preso la decisione, è necessario configurare Oracle per contenere i dati in tale charset e scegliere un tipo di colonna appropriata. Per esempio, VARCHAR2 va bene per ASCII, NVARCHAR2 è un bene per UTF-8.
Se davvero non si può cambiare il set di caratteri che Oracle utilizzerà allora come di Base64 codifica i dati prima di riporla nel database. In questo modo, è possibile accettare i caratteri da qualsiasi set di caratteri e memorizzarli come ISO-8859-1 (perché Base64 emetterà un sottoinsieme del set di caratteri ASCII che associa esattamente a ISO-8859-1). codifica base64 aumenterà la lunghezza della stringa, in media, 37%
Se i dati sono sempre e solo sta per essere visualizzato come HTML, allora si potrebbe anche memorizzare entità HTML come lei ha suggerito, ma essere consapevoli del fatto che una singola entità può essere fino a 10 caratteri per carattere non codificato per esempio θ è ϑ
ho dovuto affrontare questo problema: i caratteri speciali Latinamerican vengono memorizzati come "?" o "¿" nel mio database Oracle ... Non posso cambiare il NLS_CHARACTER_SET perché non siamo i proprietari del database.
Quindi, ho trovato una soluzione:
1) codice ASP.NET Creare una funzione che converte stringa in caratteri esadecimali:
public string ConvertirStringAHex(String input)
{
Encoding encoding = System.Text.Encoding.GetEncoding("ISO-8859-1");
Byte[] stringBytes = encoding.GetBytes(input);
StringBuilder sbBytes = new StringBuilder(stringBytes.Length);
foreach (byte b in stringBytes)
{
sbBytes.AppendFormat("{0:X2}", b);
}
return sbBytes.ToString();
}
2) Applicare la funzione di cui sopra per la variabile che si desidera codificare, come questo
myVariableHex = ConvertirStringZHex( myVariable );
In Oracle, utilizzare il seguente:
PROCEDURE STORE_IN_TABLE( iTEXTO IN VARCHAR2 )
IS
BEGIN
INSERT INTO myTable( SPECIAL_TEXT )
VALUES ( UTL_RAW.CAST_TO_VARCHAR2(HEXTORAW( iTEXTO ));
COMMIT;
END;
Naturalmente, iTEXTO è il parametro di Oracle, che riceve il valore di "myVariableHex" dal codice ASP.NET.
Speranza che aiuta ... se c'è qualcosa per migliorare pls non esitare a pubblicare i tuoi commenti.
Fonti: http: / /www.nullskull.com/faq/834/convert-string-to-hex-and-hex-to-string-in-net.aspx https://forums.oracle.com/thread/44799