Путь ASP.NET → PHP
Так получилось, что в сентябре прошлого года назад я перешел в компанию, где основным языком бэкенд-разработки был PHP 7. До этого технологии с которыми я работал ограничивались C#, ASP.NET, Javascript (JQuery, Angular 1.x, Typescript), MS SQL, IIS и Windows Server. Теперь же предстояло погружение в новый стек. Данная статьи — не очередной наброс на вентилятор для поддержки холивара. Постараюсь отметить, что показалось необычным или непривычным. Статья обращена к .net разработчикам, но, надеюсь, будет интересна и PHP сообществу.
Начнем с сессии
ASP.NET поддерживает несколько режимов работы с сессией. Самый простой и стандартный режим In-proc: данные сессии хранятся в памяти процесса, в домене приложения. С любой страницы можно обратиться к Session[«key»] и получить или сохранить данные. В PHP можно выделить два стандартных механизма работы с сессией — файлы и memcached. При работе с сессиями проявляется основное отличие ASP.NET и PHP: сохранение состояния. ASP.NET — это приложение, которое работает некоторое длительное количество времени. У этого приложения есть стек, куча, общие статические переменные. Каждый запрос — новый тред внутри общего процесса. Запросы легко могут взаимодействовать через shared memory процесса. PHP наоборот по своей сути ближе к stateless природе HTTP. Каждый реквест — новый короткоживущий процесс. В памяти процесса ничего не остается между запросами, как и самого процесса. Можно, конечно, передавать объекты через shared memory, но так не особо принято. Лучше хранить данные в файлах, БД и памяти с использованием таких инструментов как memcached. Через session_set_save_handler()
можно хранить сессии где угодно.
Синтаксис, типизация и переменные
С одной стороны синтаксис си-подобный и не вызывает с непривычки явного замешательства как, например, синтаксис Python или Clojure. C другой стороны в C# я привык, что есть точка и она для всего. В PHP для обращения к членам экземпляра класса используется ->
(стрелка, T_OBJECT_OPERATOR). Для доступа к статическим членам и константам используется ::
(двойное двоеточие, Оператор разрешения области видимости). Постоянно путался, но потом привык.
Хуже дела обстоят с переменными. Они нетипизированы, их можно не инициализировать, нету никакого стартового объявления.
Это вполне валидный код. Как вы могли заметить перед именем используется $, первое время я про него забывал)
В PHP есть пара необычных вещей.
1. Переменные переменных.
2. Передача по ссылке работает не так как в .net!
Как видим из примера в документации, ссылка — это псевдоним (алиас) к другой переменной. В .net вывелось бы две разные строки даже безотносительно иммутабельности строк.
Сравнение строк, чисел, объектов.
C# изначально имеет строгие политики сравнения и приведения типов. К сожалению, PHP имеет ряд недостатков, которые упрощают жизнь на простых проектах, но приводят к тому, что обычное сравнение очень часто вызывает недоумение. В оф. доке написано так:
$a == $b TRUE if $a is equal to $b after type juggling.
Проблема в том, что правила для juggling назубок знают не многие и они могут быть неочевидными.
Коллекции
В .net есть десятки готовых типов и интерфейсов коллекций, в зависимости от поведения, которое нам необходимо, мы выбираем Queue или ConcurrentDictionary, IList или Hashtable. На собеседованиях проскакивают вопросы про типы коллекций, про отличия интерфейсов и так далее.
В PHP есть только ассоциативный массив (набор пар ключ-значение), других коллекций нет.
Из документации:
Этот тип оптимизирован в нескольких направлениях, поэтому вы можете использовать его как собственно массив, список (вектор), хэш-таблицу (являющуюся реализацией карты), словарь, коллекцию, стэк, очередь и, возможно, что-то еще. Так как значением массива может быть другой массив PHP, можно также создавать деревья и многомерные массивы.
UPD от oxidmod: в SPL есть структуры данных.
Многопоточность
Вы привыкли к многопоточности в .net. Редкое собеседование обходится без вопросов про потоки, пул, lock, async-await и т.п. В PHP многопоточности и асинхроности нет*. Буду рад, если вы поделитесь вашим опытом асинхронного PHP (web) в комментах.
* В PHP есть pthreads, в PHP есть такие проекты как ReactPHP. Но если говорить про web-проекты, я не раз слышал мнение, что PHP не предполагает асинхронных операций.
Инструменты
Visual Studio — один из самых весомых аргументов в пользу дотнет. Бесплатная IDE с богатейшим функционалом является хорошим подспорьем в работе. Добавим сюда решарпер и статическую типизацию и получим удобный набор для разработки, навигации по проекту и рефакторингу. Кроме того недавно зарелизили Rider, который в чем-то даже превосходит привычную Visual Studio. Но windows-only .net-мира являлось сильным тормозом для развития платформы и инструментария вокруг. Надеюсь, что .net core станет новым драйвером платформы.
Если говорить про PHP, то основной средой на текущей момент стала PHPStorm от той же Jetbrains. Строгая типизация только проникает в PHP7, и это усложняет проведение рефакторинга и статического поиска ошибок. Различные нововведения в области type-hinting в последующих версиях языка сделают инструментарий мощнее и лучше.
Также необходимо отметить, что PHP изначально разрабатывался для *nix-платформ и большинство инфраструктурных проектов тоже, все это делает использование таких вещей как docker, mysql, nosql более легким и естественным. Кроме того, такие проекты зачастую являются бесплатными, что обеспечивает широкое распространение. Большинству проектов на PHP не нужны windows-решения вовсе.
Книги
Вот тут все плохо у PHP (на русском). Так как язык кардинально меняет подходы, то покупать и читать книги про PHP 5.x — пустая трата времени и денег. По 7 версии на озон сейчас три книги. Я купил себе Котерова и в целом доволен. И жду пятое издание книги по паттернам и подходам в PHP (выход в очередной раз перенесен, теперь на весну 2018). Первую можно сравнить с Троелсоном (по размеру и глубине). Вторую очень хвалят, как выйдет — обязательно ознакомлюсь. Топ моих книг по .net — Альбахари, Рихтер, Цвалина и Эспозито. Возможно стоит в ближайшее время ждать больше фундаментальных книг по PHP7, но прямо сейчас не нашел актуальных книг, сравнимых по глубине с указанными. Буду рад, если подскажите!
Проекты
Дотнет — это фреймворк общего применения. Вы можете на нем писать десктопные приложения, мобильные приложения, сайты, вебапи и т.д. Есть даже такие разработки как Netduino и .NET Micro Framework. PHP все же больше про веб (либо какие-то фоновые задачи на основе той же кодовой базы, что и основной веб-проект).
На самом деле много типов задач реализуют на PHP: парсеры, чатботы и прочее. Но первым контактом с PHP у большинства разработчиков являются веб-проекты.
И именно в вебе PHP представлен намного шире, если считать поштучно, то PHP скорее всего останется лидером еще долго. Да и по уникам вряд ли PHP превратится в аутсайдера: огромное количество сайтов на PHP являются известными проектами с большой аудиторией: vk, avito, badoo.
Развитие языка
Здесь, как мне кажется, принципиальная разница. PHP драйвится сообществом. Новые фичи прилетают в виде RFC, их обсуждают, за них голосуют, включают в релизный план и т.д. У дотнет есть владелец — Microsoft. Сейчас они сделали пивот в сторону опенсорса, они всегда слушали сообщество, но решения принимают достаточно авторитарно. Не знаю какой вариант лучше, есть плюсы и там и там. Развитие дотнет последовательнее и предсказуемее. с другой стороны фича может лежать без движения вечно, так как комитет считает, что прямо сейчас она не отвечает потребностям языка.
Мы видим как развивается C# и .Net. Лично я начинал с 1.1 — помню как появились генерики, linq, TPL. Это было круто. Но все как-то укладывалось в общую канву. Первый дотнет изначально смотрел на готовую Java и принятые там подходы. C# не менялся драматично, как мне кажется.
У PHP более извилистый путь (почитать на Хабре). Язык изначально отличался легкостью освоения, максимальной дружелюбностью к некачественному коду. На нем быстро и без специальных знаний можно было сделать достаточно сложный веб-сайт. В веб-разработку потянулось огромное количество людей без каких-то специальных навыков. В этот период стартовали тысячи проектов, которыми мы так или иначе пользуемся и сейчас. Сложно переоценить вклад PHP в развитие веба. Индустрия росла, появились деньги, появились эксперты, назрела необходимость рефакторинга легаси проектов. И стало понятно, что изначальный код невозможно поддерживать методами известными в индустрии. В итоге PHP сделал разворот в сторону хороших практик: ООП, типизация. Но все еще оставил часть былой легкости.
Работа
Я всегда думал, что зарплата в дотнет-мире выше, и это, в целом, правда, если судить по средней по больнице. Но есть один нюанс: на рынке катастрофически не хватает PHP-разработчиков, которые знают что такое ООП, паттерны, SOLID и умеют это использовать. Как я писал проекты выросли и обросли деньгами и кучей кода, появились фреймворки, на которых можно начинать новые проекты (Symfony, Yii, Laravel). Все это привело к увеличению спроса. И крупные успешные компании готовы платить хорошие деньги. В итоге, PHP-разработчик сейчас может претендовать даже на большие деньги при сопоставимом уровне скиллов.
Заключение
В целом язык более «магичен» (магические методы, жонглирование при сравнении) и прощает множество ошибок. Про MS SQL vs MySQL можно пачку таких же постов написать. Значимых отличий и интересных особенностей сильно больше, чем я уже указал: конкатенация точками, трейты, интерполяция строк в двойных кавычках и т.д. Я выбрал лишь некоторые — остальные можем обсудить в комментариях.
Я рад видеть, что современный PHP 7 все больше похож на известный мне C#! Коллеги, кто до сих пор относится с пренебрежением к PHP — я ответственно заявляю, что это совсем другой язык и вы можете смело переносить свои ООП-подходы в проекты на нем.
Изучайте новые языки и технологии! Будьте лучшей версией себя!