Как сказал товарищ sectus, — token_get_all может затыкаться из-за невалидного кода.
Я проверял работоспособность на смешанном коде, типа
- Привет, друзья!
<?php
echo "<br/> - Как дела?";
?>
<br /> - Да все в порядке!
При парсинге кода я сперва разделяю код на блоки php и не-php. То, что не-php — оборачиваю в nowdoc/heredoc, а потом склеиваю. Таким образом получается монолитный php-код, который можно нормально парсить. Производительность падает, конечно, из-за такого анализа, но пока идей лучше мне не пришло.
Парсер аннотаций и регулярки конечно же могут справиться с подобной задачей, вот только это не анализ кода получается, а анализ текста. А текст, сами понимаете, может быть совсем не таким, как ожидалось.
upd: А под встроенным парсером вы что понимаете? tokenizer или либу?
У нас тоже работодатель не покупает такие продукты для разработчиков, но это не помешало нам самим купить лицензию и поддержать таким образом продукт. Хорошая работа должна быть оплачена. Мы же сами, в первую очередь заинтересованы в развитии этих замечательных IDE.
Что такое debug_backtrace() я знаю, просто в ассоциациях всплыла именно эта фишка, красиво у них она реализована. Как она устроена, я не смотрел, но предположил, что именно так ее можно реализовать. В любом случае, спасибо за поянение.
Ага, такие варианты тоже есть. Их достаточно сложно отловить, поэтому эти ситуации я не стал обрабатывать.
В таких ситуациях лучше пользоваться опцией disable_functions или расширением runkit, чтобы запретить выполнение на уровне интерпретации.
С обусфактором вопрос спорный, тут наверное все же лучше использовать какое-то готовое решение т.к. система может получиться не шуточной, но возможность такая есть конечно.
А вот с анализом коробочного продукта — идея хорошая, я приму на заметку, спасибо!
Мне казалось, я что-то подобное видел в yii. Там при ошибке/эксепшене отображалась функция, в которой это событие произошло.
Хотелось бы взглянуть на реализацию, в yii я побоялся лезть. Применение очень интересное.
Я думал над этой возможностью, но совсем сильно заморачиваться не хотелось. Пришел к выводу, что проще запретить eval() и create_function() в такой ситуации.
Специально открыл исходники composer по части генерации автозагрузчика — и увидел следующее:
// ... тут пара регулярок, затем вот это
preg_match_all('{
(?:
\b(?<![\$:>])(?P<type>class|interface'.$traits.') \s+ (?P<name>[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)
| \b(?<![\$:>])(?P<ns>namespace) (?P<nsname>\s+[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*(?:\s*\\\\\s*[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)*)? \s*[\{;]
)
}ix', $contents, $matches);
// .. еще пара регулярок
Я ничего не имею против регулярных выражений, но разобраться тут сложно, да и подход совершенно другой. Прелесть tokenizer'а в том, что он обрабатывает именно языковые конструкции, а не все подряд. Т.о. я уверен, что моя функция обработает только php-код.
Все таки сравнивать запуск из консоли с обработкой tokenizer'ом не совсем корректно. Безусловно такого же результата можно добиться и другими способами. Я привел простейший пример обработки.
Что касается composer — конечно, я знал, что у него есть такая возможность. Но опять же, мой генератор автозагрузки родился в результате экспериментов с tokenizer'ом. И он так же генерирует список всех файлов, из подпапок и подпапок подпапок.
Разница лишь в том, что тут одна функция, которая заправляет всем анализом и по которой можно понять принцип работы tokenizer'а, а composer — это пакетный менеджер, в котором ни одна тысяча строчек кода.
Я проверял работоспособность на смешанном коде, типа
При парсинге кода я сперва разделяю код на блоки php и не-php. То, что не-php — оборачиваю в nowdoc/heredoc, а потом склеиваю. Таким образом получается монолитный php-код, который можно нормально парсить. Производительность падает, конечно, из-за такого анализа, но пока идей лучше мне не пришло.
Парсер аннотаций и регулярки конечно же могут справиться с подобной задачей, вот только это не анализ кода получается, а анализ текста. А текст, сами понимаете, может быть совсем не таким, как ожидалось.
upd: А под встроенным парсером вы что понимаете? tokenizer или либу?
Еще бы ее как amd модуль оформить и в репозиторий jam'а добавить — было бы супер!
В таких ситуациях лучше пользоваться опцией disable_functions или расширением runkit, чтобы запретить выполнение на уровне интерпретации.
А вот с анализом коробочного продукта — идея хорошая, я приму на заметку, спасибо!
Хотелось бы взглянуть на реализацию, в yii я побоялся лезть. Применение очень интересное.
Я ничего не имею против регулярных выражений, но разобраться тут сложно, да и подход совершенно другой. Прелесть tokenizer'а в том, что он обрабатывает именно языковые конструкции, а не все подряд. Т.о. я уверен, что моя функция обработает только php-код.
Что касается composer — конечно, я знал, что у него есть такая возможность. Но опять же, мой генератор автозагрузки родился в результате экспериментов с tokenizer'ом. И он так же генерирует список всех файлов, из подпапок и подпапок подпапок.
Разница лишь в том, что тут одна функция, которая заправляет всем анализом и по которой можно понять принцип работы tokenizer'а, а composer — это пакетный менеджер, в котором ни одна тысяча строчек кода.