Автор Тема: PHP finfo vs command file  (Прочетена 8011 пъти)

senser

  • Напреднали
  • *****
  • Публикации: 1328
    • Профил
PHP finfo vs command file
« -: Nov 06, 2014, 18:59 »
Привет,

Работя върху web приложение за качване на файлове с PHP.
Искам да разбера какъв е mime-type на файла, който се качва. Когато използвам PHP finfo получавам "application/octet-stream; charset=binary"
Код:
$finfo = finfo_open(FILEINFO_MIME);
echo finfo_file($finfo,"File.odt");
finfo_close($finfo);

 в същото време, ако използвам  filе се получава "application/vnd.oasis.opendocument.text; charset=binary"
Код:
file -i File.odt

Поразрових се да видя дали finfo и file ползват една  и съща база с mime types. Файлът в Дебиан е "/usr/share/file/magic.mgc" (има няколко симлинка към него). Ако го използвам изрично с file, няма проблем - резултатът е същия:
Код:
file -i -m /usr/share/file/magic.mgc File.odt

Ако обаче дам същият файл на finfo_open, нещата не са ОК:
Код:
$finfo = finfo_open(FILEINFO_MIME, "/usr/share/file/magic.mgc");
echo finfo_file($finfo,"File.odt");
finfo_close($finfo);

Горното гърми с:
Код:
PHP Notice:  finfo_open(): Warning: offset `-' invalid in /home/senser/Desktop/CustomerFiles_Tests/finfo.php on line 4
PHP Notice:  finfo_open(): Warning: type `-' invalid in /home/senser/Desktop/CustomerFiles_Tests/finfo.php on line 4
PHP Notice:  finfo_open(): Warning: offset `.' invalid in /home/senser/Desktop/CustomerFiles_Tests/finfo.php on line 4
PHP Notice:  finfo_open(): Warning: type `.' invalid in /home/senser/Desktop/CustomerFiles_Tests/finfo.php on line 4
PHP Warning:  finfo_open(): Failed to load magic database at '/usr/share/file/magic.mgc'. in /home/senser/Desktop/CustomerFiles_Tests/finfo.php on line 4

В същото време finfo  с параметър празната директория "/usr/share/misc/magic", не гърми:
Код:
$finfo = finfo_open(FILEINFO_MIME, "/usr/share/misc/magic");
вади същия резултат "application/octet-stream; charset=binary".

И последно ако извикам file без да тества с magic files (от man file:  soft      Consults magic files):
Код:
file -i --exclude soft File.odt
имам "application/octet-stream; charset=binary"

Всичко това ме навежда на мисълта, че finfo на PHP не (може да) ползва същата mime types база.
Не намирам в същото време кой файл ползва вътрешно. Това, което намирам на сайта на РНР (http://bg2.php.net/manual/en/fileinfo.installation.php) е това:
The libmagic library is bundled with PHP, but includes PHP specific changes. A patch against libmagic named libmagic.patch is maintained and may be found within the PHP fileinfo extensions source.

Ето какво имам от phpinfo():
Код:
fileinfo
fileinfo support enabled
version 1.0.5
libmagic 517
« Последна редакция: Nov 06, 2014, 19:09 от senser »
Активен

4096bits

  • Напреднали
  • *****
  • Публикации: 6152
    • Профил
Re: PHP finfo vs command file
« Отговор #1 -: Nov 06, 2014, 19:53 »
Това ще свърши ли работа?
http://stackoverflow.com/questions/21906596/find-mime-type-of-file-or-url-using-php-for-all-file-format
Активен

As they say in Mexico, "Dasvidaniya!" Down there, that's two vidaniyas.

k0tka

  • Напреднали
  • *****
  • Публикации: 130
  • Distribution: Fedora 23, CentOS, Debian, OS X El Capitan
  • Window Manager: i3wm
    • Профил
Re: PHP finfo vs command file
« Отговор #2 -: Nov 06, 2014, 22:06 »
Когато използвам PHP finfo получавам "application/octet-stream; charset=binary"
Код:
$finfo = finfo_open(FILEINFO_MIME);
echo finfo_file($finfo,"File.odt");
finfo_close($finfo);

 в същото време, ако използвам  filе се получава "application/vnd.oasis.opendocument.text; charset=binary"
Код:
file -i File.odt


Здравей,
При мен finfo_open() връща: application/vnd.oasis.opendocument.text; charset=binary същото което и file -i something.odt

fileinfo 1.0.5-dev
PHP 5.3.3
CentOS 6.5

Не съм голям специалист с PHP но съдейки по тази тема Fileinfo работи с базата на file

Не съм и сигурен коя е тя:
yum whatprovides /etc/magic #празен файл
file-5.04-15.el6.x86_64 : A utility for determining file types

yum whatprovides /usr/share/misc/magic
file-libs-5.04-21.el6.x86_64 : Libraries for applications using libmagic

yum whatprovides /usr/share/mime/magic
No Matches found

Друга вариант е да използваш shell_exec() със file -i както е споменал 4096bits
Активен

"If you need an instructional video telling your users how to turn a machine off (http://windows.microsoft.com/en-gb/windows-8/how-shut-down-turn-off-pc), there’s something seriously wrong with your design." --  Andrew Gregory @ linuxvoice

senser

  • Напреднали
  • *****
  • Публикации: 1328
    • Профил
Re: PHP finfo vs command file
« Отговор #3 -: Nov 07, 2014, 07:07 »
Да, мога да използвам shell_exec(), за да извиквам file -m, но засега ще се опитам да го избегна.

Не съм голям специалист с PHP но съдейки по тази тема Fileinfo работи с базата на file

Само, че всички опити, които направих и съм дал по-горе, сочат точно обратното според мен, вкл. и това, че резултатът от finfo & file е един и същ, когато file се извиква без проверка на mime (--exclude soft).
Отделно, че в manual-a на РНР (http://bg2.php.net/manual/en/function.finfo-open.php) пише следното:
Код:
Warning
The expected magic database format changed in PHP 5.3.11 and 5.4.1.
Due to this, the internal magic database was upgraded.
This mostly effects code where an external magic database is used: reading an older magic file will now fail.

Въпросът е дали съм прав в съжденията си, че РНР си ползва собствена mime base, мога ли да я "видя" и мога ли да го накарам да ползва "/usr/share/file/magic.mgc" вместо собствената си, защото явно резултатите на file са по-реални от finfo.
Това последното е малко вероятно, както пише в manual-a: reading an older magic file will now fail, но ми е чудно какво е наложило РНР да не ползват системния magic.mgc и да почнат да си поддържат свой (единственото, което ми идва на акъла е, че е заради windowd потребителите, които за да имат поддръжка на finfo трябва да ползват http://gnuwin32.sourceforge.net/).
« Последна редакция: Nov 07, 2014, 07:40 от senser »
Активен

senser

  • Напреднали
  • *****
  • Публикации: 1328
    • Профил
Re: PHP finfo vs command file
« Отговор #4 -: Nov 07, 2014, 08:30 »
Реших да погледна сорса на fileinfo и се натъкнах на това https://github.com/php/php-src/blob/master/ext/fileinfo/create_data_file.php.

Код:
Bundle the data file - you can still use the external file if you

Явно РНР си ползва наистина собствена mime база, ако искам да ползвам системната ще трябва да се прекомпилира :(
Активен

borovaka

  • Напреднали
  • *****
  • Публикации: 1331
  • Distribution: Каквото дойде
  • Window Manager: Gnome / KDE
    • Профил
Re: PHP finfo vs command file
« Отговор #5 -: Nov 07, 2014, 09:40 »
То си пише, че ползват собствена база.
Интересното е защо резултата при теб е такъв.
Код
GeSHi (PHP):
  1. <?php
  2. $finfo = new finfo(FILEINFO_MIME);
  3. $fres = $finfo->file('test.odt');
  4. echo $fres;
Този скрипт при мен си връща application/vnd.oasis.opendocument.text; charset=binary

Ти провери ли дали нямаш сетната MAGIC env variable? Тествай с getenv, дали проблема не е от там.

Иначе правя тест на 5.5.9 и резултата е ОК.
Активен

Та извода е прост: "Колкото по-големи ла*ната - толкова по-малка щетата! ... моралната де, не материалната"

k0tka

  • Напреднали
  • *****
  • Публикации: 130
  • Distribution: Fedora 23, CentOS, Debian, OS X El Capitan
  • Window Manager: i3wm
    • Профил
Re: PHP finfo vs command file
« Отговор #6 -: Nov 07, 2014, 09:44 »
Да...

при strace -e open file -i something.odt се вижда, че file търси за няколко файла:

Код:
open("/etc/ld.so.cache", O_RDONLY)      = 3
open("/usr/lib64/libmagic.so.1", O_RDONLY) = 3
open("/lib64/libz.so.1", O_RDONLY)      = 3
open("/lib64/libc.so.6", O_RDONLY)      = 3
open("/usr/lib/locale/locale-archive", O_RDONLY) = 3
open("/usr/lib64/gconv/gconv-modules.cache", O_RDONLY) = 3
open("/etc/magic.mgc", O_RDONLY)        = -1 ENOENT (No such file or directory)
open("/etc/magic", O_RDONLY)            = 3
open("/usr/share/misc/magic.mgc", O_RDONLY) = 3
open("File.odt", O_RDONLY)

В същото време ако подам /usr/share/misc/magic.mgc на finfo_open() не гърми с грешки и отново работи и при strace -e open php-cgi test.php се вижда:
Код:
<?php
$mimedb = "/usr/share/misc/magic.mgc";
$finfo = finfo_open(FILEINFO_MIME, $mimedb);
echo finfo_file($finfo,"File.odt");
finfo_close($finfo);
?>
Код:
open("/usr/share/misc/magic.mgc", O_RDONLY) = 3

И се чудя ако опиташ с моя /usr/share/misc/magic.mgc дали ще заработи...  ::)
Активен

"If you need an instructional video telling your users how to turn a machine off (http://windows.microsoft.com/en-gb/windows-8/how-shut-down-turn-off-pc), there’s something seriously wrong with your design." --  Andrew Gregory @ linuxvoice

senser

  • Напреднали
  • *****
  • Публикации: 1328
    • Профил
Re: PHP finfo vs command file
« Отговор #7 -: Nov 07, 2014, 10:23 »
То си пише, че ползват собствена база.
Интересното е защо резултата при теб е такъв.
Код
GeSHi (PHP):
  1. <?php
  2. $finfo = new finfo(FILEINFO_MIME);
  3. $fres = $finfo->file('test.odt');
  4. echo $fres;
Този скрипт при мен си връща application/vnd.oasis.opendocument.text; charset=binary

Ти провери ли дали нямаш сетната MAGIC env variable? Тествай с getenv, дали проблема не е от там.

Иначе правя тест на 5.5.9 и резултата е ОК.

Това зависи от файла, с който тестваш. В 90% от случаите odt файловете се разпознават коректно. Но има едни файлове, за които mime-type-а  се различава по начина, който съм описал. Навсякъде, където по-горе съм използвал File.odt съм имал впредвид такъв файл. Ако направя нов файл с офис-пакета, сейвна го и после му проверя mime-type всичко е наред - и file и fileinfo го  разпознават еднакво.
File.odt се отваря нормално от офиса пакета. Интересно, че ако го конвертирам с нещо такова:
Код:
libreoffice --headless --invisible --norestore --nologo --nolockcheck --nodefault --convert-to odt File._odt
конвертираният файл отново се разпознава като "application/octet-stream"  с fileinfo.

И се чудя ако опиташ с моя /usr/share/misc/magic.mgc дали ще заработи...  ::)

Не вярам, но ако държиш може да опитаме. Форматът, който ползва РНР се различава от този в mime.mgc - виж скрипта, който съм дал за конвертиране.
Тъпото е, че РНР-то се опъва при компилацията от сорс (current debian jessie/sid) с грешки:
Код:
undefined reference to symbol 'pthread_mutexattr_settype@@GLIBC_2.2.5'
...
undefined reference to symbol 'DSA_get_default_method@@OPENSSL_1.0.0'
Активен

k0tka

  • Напреднали
  • *****
  • Публикации: 130
  • Distribution: Fedora 23, CentOS, Debian, OS X El Capitan
  • Window Manager: i3wm
    • Профил
Re: PHP finfo vs command file
« Отговор #8 -: Nov 07, 2014, 10:31 »
ъъъъъ чакай, ако има няколко типа odt то вероятно и при мен/нас няма да работи...аз тествах с първия който намерих... ако искаш изпразни файла и дай да тестваме пак.
Иначе ето го: http://cl.ly/1k0d3O1z390i

Активен

"If you need an instructional video telling your users how to turn a machine off (http://windows.microsoft.com/en-gb/windows-8/how-shut-down-turn-off-pc), there’s something seriously wrong with your design." --  Andrew Gregory @ linuxvoice

borovaka

  • Напреднали
  • *****
  • Публикации: 1331
  • Distribution: Каквото дойде
  • Window Manager: Gnome / KDE
    • Профил
Re: PHP finfo vs command file
« Отговор #9 -: Nov 07, 2014, 10:33 »
Дам, ако е възможно качи някъде такъв файл да се тества.
Иначе опитах с конвертиран файл и отново резултата е нормален.
Активен

Та извода е прост: "Колкото по-големи ла*ната - толкова по-малка щетата! ... моралната де, не материалната"

4096bits

  • Напреднали
  • *****
  • Публикации: 6152
    • Профил
Re: PHP finfo vs command file
« Отговор #10 -: Nov 07, 2014, 12:09 »
Ами това би трябвало лесно да може да се оправи, но ако си програмист. Явно РНР гледа хедъра на файла, за да определи mime типа. Това *.нещо-си-накрая не го ли отбелязва?!
Активен

As they say in Mexico, "Dasvidaniya!" Down there, that's two vidaniyas.

senser

  • Напреднали
  • *****
  • Публикации: 1328
    • Профил
Re: PHP finfo vs command file
« Отговор #11 -: Nov 08, 2014, 07:37 »
Ето примерен файл: https://www.dropbox.com/s/vb7ha6bi8wp8bf2/ODT_Not_ODT.odt?dl=0
Активен

borovaka

  • Напреднали
  • *****
  • Публикации: 1331
  • Distribution: Каквото дойде
  • Window Manager: Gnome / KDE
    • Профил
Re: PHP finfo vs command file
« Отговор #12 -: Nov 08, 2014, 11:59 »
Интересно при мен отново си работи както трябва:

Код
GeSHi (PHP):
  1. <?php
  2. $finfo = new finfo(FILEINFO_MIME,'/usr/share/misc/magic.mgc');
  3. $fres = $finfo->file('ODT_Not_ODT.odt');
  4. echo $fres;

Изход:
application/vnd.oasis.opendocument.text; charset=binary

Според мен нещо при компилацията на пакетите при Debian е сбъркано. Опита ли да прекомпилираш директно от сорс?
Активен

Та извода е прост: "Колкото по-големи ла*ната - толкова по-малка щетата! ... моралната де, не материалната"

senser

  • Напреднали
  • *****
  • Публикации: 1328
    • Профил
Re: PHP finfo vs command file
« Отговор #13 -: Nov 08, 2014, 13:25 »
Интересно при мен отново си работи както трябва:

Код
GeSHi (PHP):
  1. <?php
  2. $finfo = new finfo(FILEINFO_MIME,'/usr/share/misc/magic.mgc');
  3. $fres = $finfo->file('ODT_Not_ODT.odt');
  4. echo $fres;

Изход:
application/vnd.oasis.opendocument.text; charset=binary

С коя версия на РНР си, какво имаш в phpinfo() за fileinfo?

Според мен нещо при компилацията на пакетите при Debian е сбъркано. Опита ли да прекомпилираш директно от сорс?

Да по-горе писах - гърми при конфигурирането на сорса още с
Код:
checking for mysql_close in -lmysqlclient_r... no
checking for mysql_error in -lmysqlclient_r... no
configure: error: mysql configure failed. Please check config.log for more information.
debian/rules:287: recipe for target 'configure-apache2-stamp' failed
make: *** [configure-apache2-stamp] Error 1

В config.log грешката е:
Код:
configure:59703: checking for mysql_close in -lmysqlclient_r
configure:59728: x86_64-linux-gnu-gcc -o conftest -I/usr/include -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -O2 -Wall -fsigned-char -fno-strict-aliasin
g   -g -D_FORTIFY_SOURCE=2 -L/usr/lib/x86_64-linux-gnu -L/usr/lib -Wl,-z,relro -L/usr/lib/x86_64-linux-gnu conftest.c -lmysqlclient_r  -lonig -lstdc++ -lcrypto -lssl -ldb -l
qdbm -lbz2 -lz -lpcre -lcrypto -lssl -lrt -lm -ldl -lnsl  -lxml2 -lgssapi_krb5 -lkrb5 -lk5crypto -lcom_err -lxml2 >&5
/usr/bin/ld: /usr/lib/libmysqlclient_r.a(my_thr_init.c.o): undefined reference to symbol 'pthread_mutexattr_settype@@GLIBC_2.2.5'
//lib/x86_64-linux-gnu/libpthread.so.0: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status
Активен

borovaka

  • Напреднали
  • *****
  • Публикации: 1331
  • Distribution: Каквото дойде
  • Window Manager: Gnome / KDE
    • Профил
Re: PHP finfo vs command file
« Отговор #14 -: Nov 08, 2014, 14:33 »
fileinfo version   1.0.5-dev, версията на PHP e 5.5.9

Ти коя версия се опитваш да компилираш, с какви флагове на configure?

Виж дали това ще ти свърши работа за грешката която дъни pthread:
http://askubuntu.com/questions/521706/error-adding-symbols-dso-missing-from-command-line-while-compiling-g13-driver
Активен

Та извода е прост: "Колкото по-големи ла*ната - толкова по-малка щетата! ... моралната де, не материалната"

Подобни теми
Заглавие Започната от Отговора Прегледи Последна публикация
EHLO: Command unrecognized
Настройка на програми
flame 5 2908 Последна публикация Aug 12, 2014, 13:21
от BRADATA
EHLO: Command unrecognized
Хардуерни и софтуерни проблеми
flame 5 2444 Последна публикация Jan 04, 2005, 09:51
от laskov
RQ: Търся играта Missile Command
Общ форум
kill_u 3 2453 Последна публикация Jan 19, 2006, 16:02
от kennedy
Make command - проблем
Настройка на програми
nushe 14 4620 Последна публикация May 20, 2006, 22:39
от nushe
Проблем с change directory command (cd)
Настройка на програми
bulg 2 2201 Последна публикация Jan 08, 2008, 04:40
от bulg