Comment puis-je forcer PHP à utiliser le libiconv version de iconv au lieu de CentOS-installé la version de la glibc?
Le code, je travaille sur fonctionne parfaitement sur Windows XP et Mac OS X. Lorsque les tests sur CentOS (et sur Fedora et Ubuntu), il ne fonctionne pas correctement. Recherche les filets m'a conduit à la conclusion que c'est la glibc
version de la iconv
qui cause le problème. Alors maintenant, j'ai besoin de la libiconv
version de iconv
pour Zend Lucene pour fonctionner correctement.
J'ai déjà téléchargé libiconv et configuré avec --prefix=/usr/local
, make
, puis make install
sans erreurs. Il semble qu'il a été installé avec succès parce que l'exécution d' /usr/local/bin/iconv --version
dit que la version est la libiconv
. Bien qu'un simple iconv --version
donne toujours l' glibc
version.
Puis j'ai recompilé PHP à partir de la source à l'aide de --with-iconv=/usr/local
. Mais encore, la phpinfo()
est de montrer la iconv
utilisé est le glibc
version. J'ai aussi déjà essayé plusieurs autres compile en utilisant --with-iconv-dir
ou à l'aide de /usr/local/bin/php
.
Bien sûr, j'ai redémarré le serveur web après recompilation de PHP.
J'ai la ligne suivante dans mon /etc/httpd/conf/httpd.conf
:
LoadModule /usr/lib/httpd/modules/libphp5.so
et libphp5.so
est en fait dans /usr/lib/httpd/modules
.
phpinfo()
montre PHP 5.3.3. J'ai aussi yum retiré de la pré-installé PHP 5.1.* juste pour s'assurer. Mais la fonction iconv est encore en utilisant la version de la glibc.
ldd /usr/lib/httpd/modules/libphp5.so
donne
linux-gate.so.1 => (0x003b1000)
/usr/local/lib/preloadable_libiconv.so (0x00110000)
libcrypt.so.1 => /lib/libcrypt.so.1 (0x001ed000)
librt.so.1 => /lib/librt.so.1 (0x0021f000)
libmysqlclient.so.15 => /usr/lib/mysql/libmysqlclient.so.15 (0x003b2000)
libldap-2.3.so.0 => /usr/lib/libldap-2.3.so.0 (0x0026e000)
liblber-2.3.so.0 => /usr/lib/liblber-2.3.so.0 (0x00370000)
libiconv.so.2 => /usr/local/lib/libiconv.so.2 (0x00516000)
libfreetype.so.6 => /usr/lib/libfreetype.so.6 (0x002a8000)
libpng12.so.0 => /usr/lib/libpng12.so.0 (0x00228000)
libz.so.1 => /usr/lib/libz.so.1 (0x00328000)
libcurl.so.3 => /usr/lib/libcurl.so.3 (0x00f23000)
libm.so.6 => /lib/libm.so.6 (0x0033b000)
libdl.so.2 => /lib/libdl.so.2 (0x00364000)
libnsl.so.1 => /lib/libnsl.so.1 (0x0037e000)
libxml2.so.2 => /usr/lib/libxml2.so.2 (0x00f5f000)
libssl.so.6 => /lib/libssl.so.6 (0x0862c000)
libcrypto.so.6 => /lib/libcrypto.so.6 (0x04145000)
libgssapi_krb5.so.2 => /usr/lib/libgssapi_krb5.so.2 (0x08e2d000)
libkrb5.so.3 => /usr/lib/libkrb5.so.3 (0x0611a000)
libk5crypto.so.3 => /usr/lib/libk5crypto.so.3 (0x005f4000)
libcom_err.so.2 => /lib/libcom_err.so.2 (0x0024e000)
libidn.so.11 => /usr/lib/libidn.so.11 (0x071f5000)
libc.so.6 => /lib/libc.so.6 (0x08aa6000)
libpthread.so.0 => /lib/libpthread.so.0 (0x00397000)
/lib/ld-linux.so.2 (0x00251000)
libresolv.so.2 => /lib/libresolv.so.2 (0x0748a000)
libsasl2.so.2 => /usr/lib/libsasl2.so.2 (0x07ddf000)
libkrb5support.so.0 => /usr/lib/libkrb5support.so.0 (0x062b7000)
libkeyutils.so.1 => /lib/libkeyutils.so.1 (0x00369000)
libselinux.so.1 => /lib/libselinux.so.1 (0x0913b000)
libsepol.so.1 => /lib/libsepol.so.1 (0x07eb4000)
C'est un cross-post de: NullPointer.ph
ldd /usr/lib/httpd/modules/libphp5.so
et ldd /usr/libexec/httpd/httpd
spectacle? Autant que je sache, apache dépend libiconv
. Vous ne pouvez pas charger les deux version de libiconv
dans un processus.Mise à jour de question pour refléter
ldd /usr/lib/httpd/modules/libphp5.so
. La deuxième commande me donne un No such file or directory
.essayez de configurer avec
--with-iconv=shared,/usr/local
J'ai essayé celui-ci en tant que bien, mais ne fonctionne pas. Merci quand même.
OriginalL'auteur Randell | 2011-01-20
Vous devez vous connecter pour publier un commentaire.
J'ai juste changé mon php 5.3.3 de glibc iconv pour GNU libiconv à travers le manuel de la recompilation de php iconv extension. Suivez ces étapes:
php-5.3.3/ext/iconv
sous-répertoirephpize
de commande (si vous n'avez pas de commande puis installerphp-devel
package)(*) éditer le fichier de configuration (
vim configure
): ajoutericonv_impl_name=""
à 4664 ligne exacte (numéro de ligne sur la configuration de votre système peuvent être différents):./configure --with-iconv=/usr/local|grep iconv
:make
sudo make install
Et maintenant je cours
php -i|grep "iconv impl"
et a obtenu:* * * * Ce truc forces configurer pour sélectionner la GNU libiconv au lieu de glibc iconv. Par défaut, il vérifie la glibc iconv à la première étape et ne pas vérifier GNU libiconv à tous.
Je me demande pourquoi la glibc est l'implémentation par défaut utilisé pour Linux alors que libiconv est la valeur par défaut pour Mac et Windows.
Juste une tête, vous ne savez pas si cela fait une différence, mais la méthode ci-dessus n'a pas assez de travail pour moi, tout en essayant de compiler PHP 5.3.8 à partir de la source, comme le principal PHP ./configurer n'ai pas ramasser d'honneur ou de la modification de la poste/iconv/script configure. Donc, je suis allé de l'avant et fait le changement ci-dessus à la main ./script de configuration au plus haut niveau en php 5.3.8 répertoire, et cela a fonctionné comme un charme. Merci!
OriginalL'auteur linuxbuild
Votre module (
libphp5.so
) est liée à deux bibliothèques partagées qui sont de fournir le même symbole (dans ce cas, le symbole esticonv
et les bibliothèques sontlibiconv.so.2
et probablementlibc.so.6
).Lorsque cela arrive, le premier chargé de symbole est utilisé: probablement
libc.so.6
est chargé avantlibiconv.so.2
et ainsi c'est l'un vous offrant laiconv
symbole.Vous pouvez forcer la dynamique chargeur pour charger une bibliothèque avant tout autre; vous pouvez le faire en définissant la
LD_PRELOAD
variable d'environnement à la bibliothèque que vous voulez de précontrainte.Je ne suis pas un expert sur Apache, donc je ne suis pas totalement sûr de savoir comment elle fonctionne, comment elle commence son processus et quels sont les processus qu'il utilise, mais je pense que la mise
LD_PRELOAD
avant de lancer apache devrait faire l'affaire:Un petit exemple pour montrer
LD_PRELOAD
en action:Compiler
myfopen.c
comme une bibliothèque partagée (myfopen.so
): il permet de fournir unfopen
symbole (déjà défini danslibc
):Compilation
printfopen.c
comme un fichier exécutable (printfopen
) qui se contente d'afficher le résultat defopen
; va le lier à la fois contre lalibc
etlibmyfopen
(LD_LIBRARY_PATH
est requis pour permettre à l'éditeur de liens regarder pour les bibliothèques aussi dans.
):Maintenant, je suis en cours d'exécution, pour tester si
LD_PRELOAD
travaux:Par défaut des charges
libmyfopen
avantlibc
, puis j'ai essayé de forcer le chargementlibc
et puislibmyfopen
premier.Je suppose que dans votre cas,
libc
devient chargé avantlibiconv
parce que l'ancien est chargé par l'application (apache?) avant qu'il charge le module PHP.LD_PRELOAD=/usr/local/lib/libiconv.so.2
, et redémarré apache httpd mais iconv est toujours à l'aide de la mise en œuvre de la glibc. Ce qui me manque?êtes-vous sûr que le processus de chargement du module PHP ont été entamées avec les
LD_PRELOAD
variable d'environnement-il correctement défini? Essayez et inspecter PHP env vars. Peut-être que apache script de démarrage réinitialisation de l'environnement avant le début démon apache?Comment puis-je le vérifier?
essayez d'utiliser le
export
de commande à l'exportationLD_PRELOAD
à l'environnement:export LD_PRELOAD=/usr/local/lib/libiconv.so.2
. Alors si vous voulez vérifier siLD_PRELOAD
est dans l'environnement à partir de PHP, vous pouvez utiliser PHPgetenv
fonction ou$_ENV
array (pas sûr de la différence entre les deux: essayez d'utiliser les deux à la fois).OriginalL'auteur peoro
Êtes-vous sûr que
LD_LIBRARY_PATH
est correctement réglé pour httpd (serveur web)?Si pas, essayez de le définir comme:
... dans le script qui démarre le processus (c'est à dire
apachectl
).La
ldd
de sortie que vous montre semble correct, mais vous avez appeléldd
de l'utilisateur de l'environnement, et de httpd peut être différent.Elle pourrait aussi aider à définir le CHEMIN d'accès à "/usr/local/bin:${PATH}", juste au cas où.
export LD_LIBRARY_PATH="/usr/local/lib:${LD_LIBRARY_PATH}"
mais rien n'a changé.OriginalL'auteur
Je comprends que cette question est déjà répondu et presque mort, mais récemment, j'ai essayé de trouver un moyen pour compiler PHP avec libiconv car en PHP je ne pouvais pas convertir "∙" de l'UTF8 pour CP1251 même avec iconv //IGNORER.
Mais j'ai trouvé une autre solution qui a fonctionné pour moi sans recompilation (il suffit d'utiliser //TRANSLIT):
iconv("UTF8", "CP1251//TRANSLIT//IGNORER", $texte)
//TRANSLIT sera translittérer SEULEMENT caractères inconnus (pas tous, comme certains peuvent le deviner), de sorte qu'il convertit russe ё", mais translittère inconnu " ∙ " pour 0x95 (ce qui est la même dans la cible charset).
OriginalL'auteur Nopius
Je ne sais pas sur CentOS, mais dans les distributions basées sur debian, comme Ubuntu, vous pouvez choisir la version du programme que vous souhaitez lancer en définissant les liens symboliques dans /etc/alternatives.
Donc, si vous modifiez le symbolink lien /etc/alternatives/iconv pour pointer vers /usr/local/bin/iconv, de ce moment, il doit utiliser la version correcte.
http://www.debian-administration.org/articles/91
/etc/alternatives
s'applique aux exécutables, pas de bibliothèques.OriginalL'auteur Pablo Alba