В чем разница между способами тестирования (в контексте web и php)?
Опишу простыми словами для упрощения понимания.

модульное тестирование
Тестирование конкретного модуля. Обычно - это самый нижний уровень, отдельные простые классы, т.е. ниже по логике уже будут отдельные функции. Например, в JS есть класс Math - тестирование всех его методов и есть модульный тест. Конечно, границы между логическими уровнями могут быть размыты и в данную категорию вполне можно вписать класс уровнем выше. Так же, модулем может быть и что-то более сложное - опять же, много зависит от масштабов и особенностей архитектуры.

интеграционное тестирование
Интеграция - это объединение. По сути выше на один уровень над модульным тестированием. Например, класс, который внутри использует простые классы. Например, есть классы графических двухмерных фигур - например треугольник и квадрат, над ними будет класс логических операций с фигурами на какой-то плоскости - сложение, вычитание и прочее. В данном случае тестируется взаимодействие сразу нескольких классов и модулей. Если строго - то сюда можно вписать тестирование большей части внутренней логики приложения.

функциональное тестирование
Очевидно, что тестируются конкретные функции, которые есть в техническом задании. Например: когда пользователь нажимает кнопку "купить" в карточке товара - товар добавляется в корзину.
какими инструментами оно делается?
Инструментами автоматизации GUI - для сайтов это Selenium и браузеры. Для десктопных/мобильных приложений аналогичные решения.

приемочное тестирование
в че отличие от интеграционных.. еще видел фразу что тут и фронт и бек тестируются, но яснее не стало, какими инструментами оно делается?
"Бизнес" заказал в "Конторе" разработку сайта, выдал ТЗ, контора сделала сайт, бизнес заплатить денег обещал. Как бизнес проверит что контора сделала именно то, что он хотел? Через приемочное тестировние - бизнес получает доступ к сайту и проверяет, что сайт именно такой, какой он заказывал в ТЗ, а не тот, который сделали индусы за доширак. Если в ТЗ указан конкретный список тестов/фич - используется этот список или так, как прописано в ТЗ само тестирование. Само тестирование проводит соответствующий специалист (инженер отдела качества) - тыкает все кнопочки, нажимает менюшечки и говорит начальству "все окей, подписывай и платим им деньги" или "вот тут и тут не окей, не подписывай, денег не давай". Реальный пример: была заказана и собрана станция спутниковой связи, на приемке были представители заказчика и исполнителя, была толстая пачка бумаги на несколько сотен страниц, по которой первые проверяли что все работает именно так, как там написано в течении нескольких недель (плюс-минус), а вторые исправляли косяки показывали что все окей, потом все поставили свои галочки и крестики и разъехались по домам.

E2E - тут тестируется чрез браузер, с помощью Mocha и тп, те тестируются "требования бизнеса к приложению", тестируются пользовательские сценарии.. а в чем отличие от функциональных тестов тогда?
Сквозное тестирование. Это полная проверка от начала и до конца. Отличие от функционального в том, что это более комплексный тест. Если функциональное тестирование - это проверка конкретной функции, тот сквозное - работа всего приложения, т.е. более комплексное. Например, E2E тест приложения для загрузки файла на сервер: тест включает в себя запуск приложения, авторизация пользователя, выбор файла, указание мета информации, загрузку файла на сервер, выход из приложения. Вот тут неплохая статья на хабре: https://habr.com/ru/company/otus/blog/681066/

Совсем запутался, с unit только понятно, а как уложить и разделить остальные?

Картинка отсюда: https://www.rainforestqa.com/blog/the-layers-of-te...
юнит - тестирование минимального модуля, обычно один класс.

Интеграционный - тестирование нескольких модулей или компонентов, которые могут разрабатывать разные люди. Соответственно у них может быть разное версионирование, или внедрение новой фичи, которая требует изменений обоих модулей может не совпасть по времени. Надо тестировать чтобы убедиться что обе стороны работают.

Функциональный - тестируем полноценно какую-то функцию, например пользовательский юзеркейс, который для работы может использовать один юнит, а может и десять.

Приемочное тестирование - когда заказчику отдаешь продукт, нужно чтобы заказчик сказал окей, все согласно договору, меня устраивает, вот твои деньги. А чтобы заказчик не трахал тебе мозг, в техническом задании могут быть описаны критерии, которые должны быть, и тесты этих критериев покажут что продукт целиком готов согласно технического задания.

e2e - енд ту енд, тестирование от начала до конца какой-то функциональности. Оно не совсем в эту иерархию вписывается. Скорее как тест, который имитирует работу пользователя. Например юнит тест можно сделать внутренними инструментами, интеграционный тоже. А e2e должен ну как минимум имитировать реального пользователя или реальное окружение как продукт будет использоваться.