Задать вопрос
  • Как перенять объектно-ориентированное мышление?

    tzlom
    @tzlom
    Очень просто.
    Для начала - признайтесь себе что процедурное программирование у вас тоже страдает (иначе бы у вас не было этого вопроса), это не страшно, но с этим тоже надо что-то решать.
    Берёте любой свой процедурный проект (лучше маленький чтобы не застрять в рутине).
    Шаг первый - всё есть функция, поэтому весь код вне функций кладёте в функции, итого у вас получается что вне функций идёт только вызов main() (или как вы её назовёте)
    Второй шаг - функции работают только с тем, что в них передали. Удаляете глобальные переменные.
    Появляется проблема глубокой вложености, т.е. у вас внутри вызова А вызывается Б а в ней В которая хочет переменную из области видимости А, и таких случаев много. Тащить в Б все эти переменные - грустно и печально, поэтому делаем хитрость, каждая функция первым аргументом получает массив неких значений. Правило одно - функции не меняют имена и количество переменных в массиве, только значения.
    Третий шаг - функции должны быть короткими, выносите повторяющийся код в отдельные функции, если в функции используется много переменных - это повод разбить её на несколько меньших.
    Четвёртый шаг - вы уже пишете на ООП. Если 3 шага правильно сделаны, то осталось только оформить это дело согласно новым правилам - первый аргумент-массив это члены класса, соответственно функции использующие одинаковый массив - методы этого класса, прийдётся разобраться с доступом к полям и отдельными зависимостями, но это уже будет просто и понятно когда ты до этого доберёшься.
    Ответ написан
    4 комментария
  • Как перенять объектно-ориентированное мышление?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    Т.е. сложно понимаю, что "засунуть" в один объект, что в другой, что должно быть статическим методом, что приватным и тд.


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

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

    Теперь задумаемся о декомпозиции всего этого хаоса. Мы находим какую-то задачу, которую выполняет наш код (например какую функцию вызвать для обработки каждого конкретного запроса) и выносим это в отдельный объект. Отправка email-ов - отдельный объект. Весь SQL зашиваем в отдельный объект. Соединение с базой - объект. Пользователи - объекты. Все - объекты.

    И главное, у каждого объекта есть своя область ответственности. UNIX way. Каждый объект делает что-то одно и делает это хорошо. Бывает так что ну... нужно сделать так что бы один объект делал две вещи. НЕ вопрос, мы можем его попросить сделать что-то сложное, а он будет как хороший менеджер тупо делегировать работу другим объектом. То есть он и сложную штуку сделает, и сам не будет знать как она делается.

    А все безхозные функции, которые не пренадлежат никаким объектам (например функции порождающие объекты) можно вынести в статические методы. Главное что бы статичесих переменных у нас небыло (ибо это те же глобальные переменные). И поменьше публичного ибо черт его знает что эти разработчики будут использовать. Причем "те разработчики" это вы завтра.

    Вообщем писав всё время на процедурке, сложно перейти на ооп.


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

    Вы можете начать погружаться в ООП с того, что разобраться "почему глобальные переменные это плохо", почему "состояние порождает сложность" и что такое эта "сложность" (многие почему-то думают что сложность выражается в написании кода а не в его чтении или поддержке), почему "изоляция" (и как следствие инкапсуляция) - это хорошо. Как это все соотносится с декомпозицией. Что такое "ответственность", что такое зависимости, связанности

    Подскажите, какой проект начать писать (гостевая, блог), или может начать изучать фреймворк.


    Фреймворки универсальны, а значит чистого ООП там быть не может. Во всяком случае нет ни одного фреймворка на котором стоит учиться ООП.

    Есть хорошие упражнения на развитие понимания объектно-ориентированного проектирования. Например вот: https://habrahabr.ru/post/206802/

    Сразу хочу отметить что это крайности. Упражнения же. Они должны ограничивать вас что бы заставлять думать и задавать правильные вопросы.

    Или может подскажите книгу/сайт где пошагово в ооп написан какой-то проект, чтобы быстрее пришло понимание.


    Так вы научитесь делать один конкретный проект а на втором вы уже проиграете. Так дела не делаются. Надо разобраться с причинами появления идеи ООП. Ну то есть что было до. Можно еще с функциональным программированием попробовать разобраться. В PHP оно слабо применимо, но основные идеи очень тесно переплетаются с ООП и познав немного функциональщины ваше ООП будет лучше. Да и если про ООП вы можете найти много булшита, про функциональщину врут мало.
    Ответ написан
    3 комментария
  • В 40 лет планирую поменять сферу деятельности с 1С на Android? Сколько на старте смогу зарабатывать?

    alexgp13
    @alexgp13
    Руководитель ИТ-проектов
    Я бы сказал, что у Вас неправильная постановка задачи. Не ставьте себе цель спрыгнуть с опытного 1Сника на джуна в Андроид, ставьте целью получить необходимый опыт и идти на хорошую должность. Или начинать свое дело.
    ЗП начинающего разработчика около 1000 долларов, так что просадка в деньгах будет ощутимая, в свое время сам пытался спрыгнуть так с 1С на php.
    p.s. напишите в ТГ, есть кое-какие мысли
    Ответ написан
    Комментировать
  • В 40 лет планирую поменять сферу деятельности с 1С на Android? Сколько на старте смогу зарабатывать?

    solotony
    @solotony
    покоряю пик Балмера
    Как работодатели смотрят на 40 летних программистов?


    нормально, если с опытом и если башка еще работает

    особенно тех кто стартует в этом возрасте?


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

    что бы "с 0" более-менее сносно освоить новую технологию надо пару тыщ часов на нее потратить учитывая что опыт программирования есть - не совсем с "0"

    "жена и дети" - ну так продай машину, возьми кредит
    Ответ написан
    Комментировать
  • В 40 лет планирую поменять сферу деятельности с 1С на Android? Сколько на старте смогу зарабатывать?

    @nApoBo3
    Без просадки, особенно в 40 лет с детьми мало реально, возможно, но имхо это из области фантастики.
    Ответ написан
    3 комментария
  • В 40 лет планирую поменять сферу деятельности с 1С на Android? Сколько на старте смогу зарабатывать?

    @AndromedaStar
    .Net - monkey
    У вас прекрасный возраст, сейчас на это уже не смотрят. Причём ещё есть отличный опыт в финансовой сфере скорее всего, опыт коллективной разработки. Это как раз вас и отличает от зелёного джуна.
    Но. В нашу команду мы очень стараемся не брать женатых или замужем людей. Нам все равно на пол, возраст, национальность, как и всем адекватным людям. Но, к сожалению, семья отнимает слишком много сил и энергии, это считай вторая, ещё более ответственная работа. И в режиме сверхинтенсивной разработки, как в стартапе, разница между человеком без семьи и с семьёй видна сразу. Ну вот раньше в офисе сразу было видно, что у человека голова часто занята не тем, а это сказывается на перфомансе. Плюс вам будет сложнее уделить все выходные учёбе. Ну все мы люди, все понимаем.
    То есть подводя итог, недостаток времени и сил из-за семьи может очень сильно помешать. Вот если конечно попасть в какой-то полусонный финансовый энтерпрайз, там может и по другому. Так что я бы на это на вашем месте ориентировался.
    Ответ написан
    23 комментария
  • Порядок ваших действий при создании сервисов на Docker?

    @XEHKOK
    Я обычно стягиваю конфиги софта для новых проектов из оф образов.
    1) Можно как просто запулить сбилдить и запустить софт, так и через Dockerfile или даже docker-compose up -d --build, это уже личное дело как религия позволяет)
    Вытягиваю обычно так:
    PHP:
    docker cp имя контейнера или сервиса:/usr/local/etc/php-fpm.conf /var/www/projects/mynewproject/docker/php/php-fpm.conf
    docker cp имя контейнера или сервиса:/usr/local/etc/php-fpm.d/www.conf /var/www/projects/mynewproject/docker/php/www.conf
    docker cp имя контейнера или сервиса:/usr/local/etc/php/php.ini-development /var/www/projects/mynewproject/docker/php/php.ini
    Левые пути это размещение в контейнере конфигов, правые пути это куда копировать на хост системе.
    После получения исходных конфигов прописываю их в Dockerfile сервиса PHP:
    COPY /var/www/projects/mynewproject/docker/php/php.ini /usr/local/etc/php/php.ini
    COPY /var/www/projects/mynewproject/docker/php/php-fpm.conf /usr/local/etc/php-fpm.conf
    COPY /var/www/projects/mynewproject/docker/php/www.conf /usr/local/etc/php-fpm.d/www.conf

    Правда я делаю это не через волюм конечно, но это опять же вопрос религии)

    Собственно аналогично можно вытянуть конфиги и для Nginx:
    docker cp имя контейнера или сервиса:/etc/nginx/nginx.conf /var/www/projects/mynewproject/docker/nginx/nginx.conf
    docker cp имя контейнера или сервиса:/etc/nginx/conf.d/default.conf /var/www/projects/mynewproject/docker/nginx/default.conf
    Для нового Nginx даже вроде есть файл конфига шаблона: /etc/nginx/templates/default.conf.template, который можно взять за основу для виртуалхостов nginx.
    Ну а для БД и прочего софта думаю не составит труда поковырять оф образы или погуглить)

    2) Если правильно понял на счет модулей ext-php:
    Тут несколько вариантов модули которые входят в базовую сборку php можно установить так:
    RUN docker-php-ext-install -j$(nproc) soap
    Те которые нужно установить и принудительно включить:
    RUN docker-php-ext-install -j$(nproc) opcache && docker-php-ext-enable opcache
    Еще есть которые нужно конфигурировать вроде zip:
    RUN apt-get update && apt-get install -y --no-install-recommends libzip-dev zip
    RUN docker-php-ext-configure zip && docker-php-ext-install -j$(nproc) zip
    А еще можно ставить из PECL расширения на примере pthreads:
    RUN pecl install pthreads && docker-php-ext-enable pthreads

    В общем докенезировать можно php проект главное знать основы докера и специфику софта который нужно в этом самом докере поднять.
    Ответ написан
    Комментировать
  • Почему возникает ошибка php при docker-compose build?

    svisch
    @svisch Автор вопроса
    Решил следующим образом:
    Из файла Dockerfile удалил следующие строки. В консоли именно на этот пакет ругался. Не знаю за что он отвечает, но без него все завелось нормально
    # Install composer plugins
    RUN composer global require --optimize-autoloader \
            "hirak/prestissimo:${VERSION_PRESTISSIMO_PLUGIN}" && \
        composer global dumpautoload --optimize && \
        composer clear-cache
    Ответ написан
    Комментировать
  • Docker-composer - рабочий пример запуска сервера с двумя версиями php?

    dmitriylanets
    @dmitriylanets
    веб-разработчик
    хорошая практика один проект - один докер конфиг
    поэтому проекты на php5.6 и php7.3 будет иметь каждый свою версию
    поэтому шаги простые
    1. переходишь в папку проекта
    2. $ docker-compose up -d && docker-compose exec app bash
    3. $ php some_script.php
    Ответ написан
    Комментировать
  • Как сделать шаблоны в php?

    TTATPuOT
    @TTATPuOT
    https://code.patriotovsky.ru/
    Вам нужен шаблонизатор. Вариантов масса:
    Я предпочитаю Smarty почему-то.
    Ещё, очень популярен Blade в силу того, что он используется в Laravel.
    Mustache доступен не только для PHP, а ещё для массы других языков. Я его в JS использовал.
    + Twig

    Это первые, что приходят в голову. Если погуглите - найдёте ещё миллион.
    Ответ написан
    Комментировать
  • Где взять годный туториал по Composer?

    pOmelchenko
    @pOmelchenko
    php-developer
    Композер это пакетный менеджер, ты просто описываешь какие у тебя в проекте будут зависимости. Он так же рулит автозагрузкой классов.

    То есть по сути, на минималках. Любой проект будет иметь примерно следующую структуру composer json

    {
      "name": "pomelchenko/project",
      "type": "project",
      "description": "description",
      "minimum-stability": "stable",
      "license": "proprietary",
      "require": {
        "php": "^7.4",
        // тут зависимости для продакшена, когда будешь устанавливать приложение с флагом --no-dev
      },
      "require-dev": {
        "phpunit/phpunit": "^9.5"
        // тут зависимости для dev среды, с тестами и прочими инструментами которые несут вспомогательный смысл.
      },
      "autoload": {
        "psr-4": {
          "App\\": "src/"
          // тут перечисляешь нэймспэйсы и пути до директорий с классами этих нэймспэйсов для приложения, которое будет на проде крутиться
        }
      },
      "autoload-dev": {
        "psr-4": {
          "Tests\\": "tests/"
          // тут перечисляешь нэймспэйсы и пути до директорий с классами этих нэймспэйсов для вспомогательных инструментов, как правило для тестов
        }
      }
    }


    После установки у тебя появится ./vendor/autoload.php который ты во фронтконтроллер подключишь чтобы всё заработало.

    По сути всё. Остальное придет по необходимости во время работы.

    Нужны тесты? Ставишь в phpunit так, чтобы он оказался в require-dev, то есть composer require --dev ...
    Нужны пакеты для работы приложения? Например, роутер или орм, просто ставишь composer require ...

    Ничем более как менеджмент зависимостей композер не занимается. В смысле на бизнеслогику и инфраструктуру (ну кроме как автолоад классов и файлов) проекта он никак не влияет.
    Ответ написан
    Комментировать
  • Покритикуйте код! Какие грубые и негрубые ошибки совершил?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    Ну тут скорее ни одной почти строчки нормальной.
    • exit('Ошибка подключения к базе данных!'); дважды глупость. Пользователю сайта не интересно читать, что у тебя сломалось - база данных или деньги на пиво кончились. Как программисту, тебе эта бессмысленная фраза тем более бесполезна, она ничего не говорит о том, ЧТО КОНКРЕТНО сломалось, чтобы ты мог исправить
    • if ($numRows > 0) { бессмысленный кусок кода
    • while ($row = $result->fetch_assoc()) { заменяется на $result->fetch_all(MYSQLI_ASSOC)
    • $this->connect() коннектимся каждый раз, чтобы выполнить запрос, серьёзно?
    • А когда будет еще один класс, для другой таблицы, снова будешь писать код подключения к БД? И так в каждом?
    • Почему класс для работы с "позициями" называется DBh?
    • По сути это не класс, а набор функций. Если ты уберешь красивые слова class и this, то НИЧЕГО не изменится
    • SQL инъекции кругом
    • class Handler extends Dbh ВООБЩЕ непонятно зачем



    В общем, как-то так
    dbh.php
    class Dbh
    {
        public $conn;
    
        public function __construct($config)
        {
            mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
            $this->conn = new mysqli(...$config);
            $this->conn->set_charset('utf8mb4');
        }
    
        public function preparedQuery($sql, $params, $types = '')
        {
            $types = $types ?: str_repeat('s', count($params));
            $stmt = $this->conn->prepare($sql);
            $stmt->bind_param($types, ...$params);
            $stmt->execute();
            return $stmt;
        }
    
        public function selectResult($sql, $params, $types = '')
        {
            if (!$params) {
                return $this->conn->query($sql);
            }
            return $this->preparedQuery($sql, $params, $types)->get_result();
        }
        public function selectAll($sql, $params = [], $types = '')
        {
            return $this->selectResult($sql, $params, $types)->fetch_all(MYSQLI_ASSOC);
        }
        public function selectAssoc($sql, $params = [], $types = '')
        {
            return $this->selectResult($sql, $params, $types)->fetch_assoc();
        }
        public function selectRow($sql, $params = [], $types = '')
        {
            return $this->selectResult($sql, $params, $types)->fetch_row();
        }
        public function selectCell($sql, $params = [], $types = '')
        {
            $row = $this->selectRow($sql, $params, $types);
            return $row ? $row[0] : false;
        }
    }

    position.php
    class Position
    {
        protected $dbh;
    
        public function __construct(Dbh $dbh)
        {
            $this->dbh = $dbh;
        }
        // Получаем все позциии из БД и возвращаем их в массиве $output если записей больше нуля
        public function getAllPositions()
        {
            return $this->dbh->selectAll('SELECT * FROM positions');
        }
        protected function addPosition($content)
        {
            $count = $this->dbh->selectCell('SELECT count(*) FROM positions');
            if ($count < 10) {
                $this->dbh->preparedQuery("INSERT INTO positions (content) VALUES (?)", [$content]);
            }
        }
        protected function deletePosition($id)
        {
            $this->dbh->preparedQuery("DELETE FROM positions WHERE id = ?", [$id]);
        }
        //Поиск позиций в БД по столбцу content
        protected function searchPosition($content)
        {
            $content = "%$content%";
            return $this->dbh->selectAll('SELECT * FROM positions WHERE content LIKE ?',[$content]);
        }
    }

    config.php
    return [
          'db' => [
              'host' => '127.0.0.1',
              'username' => '',
              'password' => '',
              'dbname' => '',
              'port' => 3306,
          ],
      ];


    handler.php

    $config = require 'config.php';
    $dbh = new Dbh($config['db']);
    $position = new Position($dbh);
    
    switch ($_GET['action']) {
        case 'getpositions':
            $output = $position->getAllPositions();
            echo json_encode($output);
            break;
        case 'addposition':
            $content = $_GET['content'];
            $position->addPosition($content);
            break;
        case 'getsearchpositions':
            $content = $_GET['content'];
            $output = $position->searchPosition($content);
            echo json_encode($output);
            break;
        case 'deleteposition':
            $id = $_GET['id'];
            $position->deletePosition($id);
            break;
        default:
            header("HTTP/1.0 400 Bad Request");
    }
    Ответ написан
    2 комментария
  • Как вывести в модальном окне подгрузку информации по выбранному элементу в PHP?

    @thisuserhatephp
    Офлайн - losers Онлайн - lusers
    Лучше бы прислушался к совету к прошлому вопросу, но вместо этого ты продублировал вопрос.
    Хотя, аякс, ты все же загуглил

    //сразу от body обращаемся, что бы избежать следующего вопроса -  "а почему не работает клик, если подгружать динамически модалку " 
    $('body').on('click', '.open-modal-work-js', function(){
        var get_id = $(this).attr("data-id");
    	$.ajax({
    		type: 'POST',
    		url: '/path-to-action.php',
    		data: {
    			id: get_id
    		},
    		success: (data) => {
    			$('.modal-window').show().html(data);
    		}			
    	});
    });


    php
    $id = $_POST['id'];
    $sql= "SELECT * FROM works WHERE id_w = ".$id." ";


    Но так категорически не советую делать, а лучше еще раз процитирую коммент с прошлого вопроса
    запрос составлен не верно и кишит sql инъекциями, предлагаю почитать что это - sql инъекции и заодно взглянуть на pdo. так же на примеры ajax запросов в связке php и mysql
    Ответ написан
    1 комментарий
  • Почему логинится под любым возможным паролем?

    yupiter7575
    @yupiter7575
    Python программист
    Берите пароль из бд, и его проверяйте
    Ответ написан
    Комментировать
  • Почему логинится под любым возможным паролем?

    @Kostik_1993
    Web Developer
    Ну так вы один и тот же пароль хешируете и сверяете с его же хешем
    Ответ написан
  • Почему не получается записать в базу данных?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    База данных всегда сама подробно расскажет, почему у неё не получилось выполнить запрос. Надо её только об этом попросить.

    Поэтому сначала учимся правильно соединяться.
    Весь этот детский лепет "не могу соединиться с БД" выкидываем и пишем нормальный код, который сам, без всяких проверок, сообщит нам об ошибках.
    В случае mysqli это
    mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
    $link = mysqli_connect($host, $user, $pass, $db_name);
    $link->set_charset("utf8mb4");

    Здесь первая строчка отвечает как раз за информирование об ошибках

    Кроме того надо не забыть про ошибки РНР
    Во-первых, всегда в коде должно быть error_reporting(E_ALL);
    Плюс на домашнем компе ini_set('display_errors',1);, а на боевом - ini_set('display_errors',0);ini_set('log_errors',1);, и смотреть, соответственно, в логах.

    После этого переписываем запрос. Причем так, чтобы данные в БД всегда попадали отдельно от самого запроса. Это непреложное правило, которое надо соблюдать всегда.
    Для этого надо
    • Заменить все переменные в запросе на специальные маркеры, которые называются плейсхолдеры или параметры, а по сути - просто знаки вопроса
    • Подготовить запрос к исполнению с помощью функции prepare(). Эта функция принимает строку запроса и возвращает экземпляр специального класса stmt, с которым в дальнейшем и производятся все манипуляции
    • Привязать переменные к запросу.
    • Выполнить подготовленный ранее запрос с помощью с помощью execute()

    В mysqli это будет так
    $sql = "INSERT INTO `events` (`title`, `discription`, `date`, `img`) VALUES (?,?,?,?)";
    $stmt = $link->prepare($sql);
    $stmt->bind_param("sssss", $title, $discription, $date, $path);
    $stmt->execute();

    bind_param() принимает в качестве параметров все переменные, которые должны попасть в запрос, в том же самом порядке, в котором стоят плейсхолдеры в запросе. Но кроме того, сначала в этой функции должны быть указаны типы для всех переменных, в виде строки, где тип переменной обозначается одной буквой. То есть букв в этой строке должно быть ровно столько, сколько дальше будет переменных. К счастью, можно особо не париться с типами и для всех переменных указывать тип "s".

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

    Но по-хорошему для работы с БД в РНР лучше использовать PDO, Тем более что там колупаться с bind_param не нужно, а можно сразу отправить все данные в execute

    Подключение
    $host = '127.0.0.1';
    $db   = 'test';
    $user = 'root';
    $pass = '';
    $port = "3306";
    $charset = 'utf8mb4';
    $options = [
        \PDO::ATTR_ERRMODE            => \PDO::ERRMODE_EXCEPTION,
        \PDO::ATTR_DEFAULT_FETCH_MODE => \PDO::FETCH_ASSOC,
        \PDO::ATTR_EMULATE_PREPARES   => false,
    ];
    $dsn = "mysql:host=$host;dbname=$db;charset=$charset;port=$port";
    $pdo = new \PDO($dsn, $user, $pass, $options);

    Здесь за информирование об ошибках отвечает параметр PDO::ERRMODE_EXCEPTION, а остальные просто для удобства/корректности.

    Выполнение запроса
    $sql = "INSERT INTO `events` (`title`, `discription`, `date`, `img`) VALUES (?,?,?,?)";
    $stmt = $link->prepare($sql);
    $stmt->execute([$title, $discription, $date, $path]);
    Ответ написан
    2 комментария
  • VK api SDK установка и подключение, как правильно?

    antoo
    @antoo
    Пришло время открывать для себя чудесный мир пакетных менеджеров!

    1. Для начала устанавливаем composer: https://getcomposer.org/doc/00-intro.md
    2. Следуя инструкции (https://github.com/VKCOM/vk-php-sdk), в папке с проектом пишем: composer require vkcom/vk-php-sdk
    3. У вас появятся файлы composer.json, composer.lock и папка vendor.
    3. Создаём рядом с ними index.php и подключаем пакеты, установленные через composer:
    <?php
    require __DIR__ . '/vendor/autoload.php'; 
    
    // теперь можем работать с VK API
    $vk = new VK\Client\VKApiClient();
    Ответ написан
    7 комментариев
  • Куда пропал EAP PhpStorm?

    ajaxtelamonid
    @ajaxtelamonid
    Laravel
    Все, цикл разработки 3.0 завершился, IDE зарелизилась, услуги бесплатных бетатестеров не нужны.
    Теперь только покупать или ждать полгода начала EAP 4й версии.
    Ответ написан
    1 комментарий
  • Могут ли как-либо достучаться до файла в не public папке?

    delphinpro
    @delphinpro
    frontend developer
    Если сервер настроен как положено, то никто не достучится.
    Как положено — это когда DOCUMENT_ROOT указывает именно на папку public, а не используются хаки для установки laravel на shared хостинг
    Ответ написан
    2 комментария
  • PhpStorm, как определить своё значение свойства?

    glaphire
    @glaphire Куратор тега PHP
    PHP developer
    Думаю что в коде какая-то ошибка и шторм правильно ругается (неправильно настроены конфиги или класс для второй базы данных).
    Самый простой способ - перед запросом сохранить $this->db2->database в переменную и над ней написать phpdoc с описанием, что она возвращает, потом уже подставлять $databaseName2 в запрос.
    /**
     * @var string $databaseName2
     */
    $databaseName2 = $this->db2->database;

    Замечание по коду - не надо так подставлять значения в строки, лучше использовать sprintf() или подставлять только итоговую переменную, а не обращение к объектам по цепочке.
    Ответ написан
    7 комментариев