Php удалить объект из памяти
Я знаю, что для некоторых, которые могут показаться глупыми, но я думал, если я hava метод delete() в классе, который удаляет все данные объекта (из базы данных и файловой системы), как я могу уничтожить/удалить объект изнутри класса.
Это вопрос PHP. Что-то вроде unset($this); Возможно ли и мудро? И каков правильный способ сделать это?
спросил(а) 2021-01-08T13:52:46+03:00 10 месяцев, 2 недели назадВо время разработки на основе я столкнулся с такой проблемой. unset($this) полностью невозможно, так как $this - это просто специальный указатель, который позволяет вам получить доступ к текущим свойствам и методам объекта.
Единственный способ инкапсулировать использование объектов в методах/функциях, чтобы при завершении метода/функции ссылка на объект терялась, а сборщик мусора автоматически освобождал память для других вещи.
См. пример RaiseFile , класс, который представляет файл:
В классе RaiseFile, это будет разумно, что после того, как вы называете delete() метод и файл будет удален, объект RaiseFile также следует удалить.
Однако из-за проблемы, о которой вы упомянули, мне действительно нужно настаивать на том, что RaiseFile указывает на файл независимо от того, существует или нет файл. Существование файла можно отслеживать с помощью метода exists() .
Скажем, у нас есть функция вырезания вставки, которая использует представление RaiseFile:
Обратите внимание, как $f удаляется и GC-ed после завершения функции, потому что больше нет ссылки на объект RaiseFile $f вне функции.
ответил(а) 2021-01-08T13:52:46+03:00 10 месяцев, 2 недели назадВы не можете отменить $this . Вернее: unset() on $this оказывает локальное влияние на переменную. unset() удаляет переменную из локальной области, что уменьшает количество ссылок для объекта. Если объект все еще упоминается где-то в другом месте, он останется в памяти и будет работать.
Как правило, значение свойства ID используется для определения того, хранится ли объект на заднем конце. Если идентификатор имеет правильное значение, этот объект сохраняется. Если идентификатор null , он еще не сохранен. При успешном хранении вы затем устанавливаете идентификатор. При удалении вы снова установите для свойства ID значение null .
ответил(а) 2021-01-08T13:52:46+03:00 10 месяцев, 2 недели назадСейчас я нахожусь в этой же лодке.
Я также использую загрузчик "Object:: getObject (id)" в каждом классе, который обеспечивает там только один экземпляр объекта на ID, но также означает, что еще проще для кода вывести ссылку на существующие объекты.
Когда данные, которые объект представляет, удаляются из источника данных, я хотел бы стереть объект из памяти и свернуть все ссылки на него, чтобы другой код не пытался использовать устаревший набор данных.
В идеале все ссылки должны быть удалены - ссылочный код может предоставить обратный вызов, который запускается при удалении объекта, который впоследствии может удалить/обновить ссылку. Но если ссылочный код становится неаккуратным, я бы предпочел, чтобы он ошибся с ошибкой "Нет объекта", чем фактически работает с объектом.
Не зная, как заставить разрушение внутри объекта, я сам вынужден:
Начните почти каждый нестатический метод с проверки, чтобы увидеть, был ли объект помечен как "удаленный", выбрасывая исключение, если оно есть. Это гарантирует, что любой ссылочный код не может навредить, но это неприятная вещь, чтобы посмотреть в коде.
Устанавливает каждую переменную объекта после удаления из базы данных, поэтому она не задерживается в памяти. Неважно, но, опять же: противно смотреть.
Ни один из них не понадобился бы, если бы я мог просто уничтожить объект изнутри.
Я знаю, что для некоторых это может показаться глупым, но я думал, что если у меня есть метод delete() в классе, который удаляет все данные объекта (из БД и файловой системы), как я могу уничтожить/удалить объект из класса.
это вопрос PHP. Что-то вроде unset($this); возможно ли и мудро? И как правильно это сделать?
при разработке на основе, я столкнулся с такой проблемой, а также. unset($this) полностью невозможно, так как $this это просто специальный указатель, который позволяет вам получить доступ к свойствам и методам текущего объекта.
единственный способ-это инкапсуляция использование объектов в методы / функции, так что, когда метод / функция заканчивается, ссылка на объект утрачены и сборщик мусора автоматически освобождает память для других вещи.
пример RaiseFile , класс, представляющий файл:
в классе RaiseFile будет разумно, что после вызова delete() метод и файл удаляется, объект RaiseFile также должен быть удален.
однако из-за проблемы, которую вы упомянули, у меня на самом деле есть настаивать на том, что RaiseFile указывает на файл независимо от того, существует файл или нет. Существование файла можно отслеживать через exists() метод.
скажем, у нас есть функция cut-paste, которая использует представление RaiseFile:
обратите внимание, как $f удаляется и GC-ed после завершения функции, потому что больше нет ссылок на RaiseFile объект $f вне функции.
вы не можете снять $this . Или правильнее: unset() on $this только локально влияет на переменную. unset() удаляет переменную из локальной области, что уменьшает количество ссылок для объекта. Если объект по-прежнему ссылается где-то еще, он останется в памяти и будет работать.
как правило, значение свойства ID используется для определения, если объект хранится в задней части. Если ID имеет правильное значение, этот объект сохраняется. Если ID null , это не хранят, пока. При успешном хранении вы затем установите ID соответственно. При удалении свойства ID устанавливается значение null снова.
Я сейчас в той же лодке.
Я также использую загрузчик" Object::getObject(id) " в каждом классе, который гарантирует, что на ID есть только один экземпляр объекта, но также означает, что для кода еще проще вытащить ссылку на существующие объекты.
когда данные, которые представляет объект, удаляются из источник данных, я хотел бы стереть объект из памяти и аннулировать все ссылки на него, чтобы убедиться, что другой код не пытается использовать устаревший набор данных.
В идеале все ссылки должны быть удалены-ссылочный код может предоставить обратный вызов, который запускается при удалении объекта, который впоследствии может удалить/обновить ссылку. Но если ссылочный код становится небрежным, я бы предпочел ошибку с ошибкой "не объект", чем фактически работать с объектом.
без зная, как заставить разрушение изнутри самого объекта, я вынужден:
начните почти каждый нестатический метод с проверки, чтобы увидеть, был ли объект помечен "удален", создавая исключение, если это так. Это гарантирует, что любой ссылочный код не может причинить никакого вреда, но это неприятная вещь, чтобы посмотреть в коде.
снимите все объектные переменные после удаления из базы данных, чтобы они не задерживались в памяти. Не большой дело, но, опять же: неприятно смотреть.
ни то, ни другое не понадобилось бы, если бы я мог просто уничтожить объект изнутри.
Это зависит от того, как вы структурировали класс.
Если вы следуете шаблонам DTO/DAO, ваши данные будут отделены от вашей модели, и вы можете просто удалить DTO. Если это не так, просто сбросить данные часть класса должна сделать это.
но на самом деле, я думаю, что это не нужно, так как PHP будет автоматически очищаться в конце запроса. Если вы не работаете над гигантским объектом, который занимает огромное количество памяти, и это долго процесс на самом деле не стоит усилий.
есть _ _ destruct () magic метод, который является деструктором для класса PHP.
возможно, вы можете поместить туда свой код удаления, и как только все ссылки на ваши объекты будут удалены, этот деструктор будет вызван, а данные удалены.
другой подход состоит в том, чтобы сделать метод delete статическим, который затем может получить объект PDO и данные, которые определяют, что удалить. Таким образом, вам не нужно инициализировать объект.
вот пример решения, которое было бы "разумно использовать" при реализации в четко определенных шаблонах отношений/ссылок, обычно я бросаю что-то подобное в своих композитах. На самом деле использовать текущий код, как я сделал в этом примере в реальной жизни, было бы слишком сложно, но это просто для иллюстрации того, как это сделать.
объект не может просто волшебным образом исчезнуть - он будет удален (собран мусор) только тогда, когда на него ничего не указывает. Поэтому" все", что должен делать объект, - это отслеживать все, что относится к нему. Это довольно низкое трение, когда у вас есть все ссылки, встроенные в объекты создаются и передаются только фиксированных методов.
давайте начнем с простого интерфейса, чтобы мы могли сказать, безопасно ли передавать нашу ссылку на объект или нет.
класс, который может безопасно хранить ссылку на наш объект.
и, наконец, класс с способность самоуничтожения ака запускает процесс удаления всеми его родителями.
и для примера использования, удерживая ссылку в array , в object реализуя наши interface и $GLOBALS array .
Я знаю, что для некоторых, которые могут показаться глупыми, но я думал, если я hava метод delete() в классе, который удаляет все данные объекта (из базы данных и файловой системы), как я могу уничтожить/удалить объект изнутри класса.
Это вопрос PHP. Что-то вроде unset($this); Возможно ли и мудро? И каков правильный способ сделать это?
спросил(а) 2021-01-08T13:52:46+03:00 10 месяцев, 2 недели назадВо время разработки на основе я столкнулся с такой проблемой. unset($this) полностью невозможно, так как $this - это просто специальный указатель, который позволяет вам получить доступ к текущим свойствам и методам объекта.
Единственный способ инкапсулировать использование объектов в методах/функциях, чтобы при завершении метода/функции ссылка на объект терялась, а сборщик мусора автоматически освобождал память для других вещи.
См. пример RaiseFile , класс, который представляет файл:
В классе RaiseFile, это будет разумно, что после того, как вы называете delete() метод и файл будет удален, объект RaiseFile также следует удалить.
Однако из-за проблемы, о которой вы упомянули, мне действительно нужно настаивать на том, что RaiseFile указывает на файл независимо от того, существует или нет файл. Существование файла можно отслеживать с помощью метода exists() .
Скажем, у нас есть функция вырезания вставки, которая использует представление RaiseFile:
Обратите внимание, как $f удаляется и GC-ed после завершения функции, потому что больше нет ссылки на объект RaiseFile $f вне функции.
ответил(а) 2021-01-08T13:52:46+03:00 10 месяцев, 2 недели назадВы не можете отменить $this . Вернее: unset() on $this оказывает локальное влияние на переменную. unset() удаляет переменную из локальной области, что уменьшает количество ссылок для объекта. Если объект все еще упоминается где-то в другом месте, он останется в памяти и будет работать.
Как правило, значение свойства ID используется для определения того, хранится ли объект на заднем конце. Если идентификатор имеет правильное значение, этот объект сохраняется. Если идентификатор null , он еще не сохранен. При успешном хранении вы затем устанавливаете идентификатор. При удалении вы снова установите для свойства ID значение null .
ответил(а) 2021-01-08T13:52:46+03:00 10 месяцев, 2 недели назадСейчас я нахожусь в этой же лодке.
Я также использую загрузчик "Object:: getObject (id)" в каждом классе, который обеспечивает там только один экземпляр объекта на ID, но также означает, что еще проще для кода вывести ссылку на существующие объекты.
Когда данные, которые объект представляет, удаляются из источника данных, я хотел бы стереть объект из памяти и свернуть все ссылки на него, чтобы другой код не пытался использовать устаревший набор данных.
В идеале все ссылки должны быть удалены - ссылочный код может предоставить обратный вызов, который запускается при удалении объекта, который впоследствии может удалить/обновить ссылку. Но если ссылочный код становится неаккуратным, я бы предпочел, чтобы он ошибся с ошибкой "Нет объекта", чем фактически работает с объектом.
Не зная, как заставить разрушение внутри объекта, я сам вынужден:
Начните почти каждый нестатический метод с проверки, чтобы увидеть, был ли объект помечен как "удаленный", выбрасывая исключение, если оно есть. Это гарантирует, что любой ссылочный код не может навредить, но это неприятная вещь, чтобы посмотреть в коде.
Устанавливает каждую переменную объекта после удаления из базы данных, поэтому она не задерживается в памяти. Неважно, но, опять же: противно смотреть.
Ни один из них не понадобился бы, если бы я мог просто уничтожить объект изнутри.
Есть ли простой способ удалить элемент из массива с помощью PHP, чтобы он foreach ($array) больше не включал этот элемент?
Я думал, что установка его null будет делать это, но, видимо, это не работает.
Я бы не сказал, что ответ Конрада является самым простым для поставленной задачи. С unset() итерациями по массиву уже не будет удалено значение. OTOH, это правда, что ответ Стевана достаточно и, на самом деле, был ответ, который я искал - но не OP :) @danip Легкость поиска в руководстве не исключает вопроса о StackOverflow. Если бы вопрос был дублирующим вопросом StackOverflow, он мог бы не принадлежать здесь. StackOverflow - это хорошее место, где можно найти ответы в качестве альтернативы, прежде чем искать в руководстве.Существуют разные способы удаления элемента массива, причем некоторые из них более полезны для некоторых конкретных задач, чем другие.
Если вы хотите удалить только один элемент массива, который вы можете использовать unset() или альтернативно \array_splice() .
Также, если у вас есть значение и вы не знаете ключ для удаления элемента, вы можете использовать его \array_search() для получения ключа.
unset()
Обратите внимание, что при использовании unset() ключей массива не будет меняться / переиндексироваться. Если вы хотите переиндексировать ключи, которые вы можете использовать, \array_values() после unset() этого все ключи будут преобразованы в цифровые ключи, начиная с 0.
\array_splice() метод
Если вы используете \array_splice() ключи, они будут автоматически переиндексированы, но ассоциативные ключи не изменятся, в отличие от \array_values() которых все ключи будут преобразованы в цифровые.
Также \array_splice() необходимо смещение, а не ключ! как второй параметр.
array_splice() такой же как unset() взять массив по ссылке, а это значит, что вы не хотите присваивать возвращаемые значения этих функций обратно в массив.
Если вы хотите удалить несколько элементов массива и не хотите вызывать unset() или \array_splice() несколько раз, вы можете использовать функции \array_diff() или в \array_diff_key() зависимости от того, знаете ли вы значения или ключи элементов, которые вы хотите удалить.
\array_diff() метод
Если вам известны значения элементов массива, которые вы хотите удалить, то вы можете использовать \array_diff() . Как и раньше, unset() он не будет изменять / переиндексировать ключи массива.
\array_diff_key() метод
Если вы знаете ключи элементов, которые вы хотите удалить, то вы хотите использовать \array_diff_key() . Здесь вы должны убедиться, что вы передаете ключи как ключи во втором параметре, а не как значения. В противном случае вы должны перевернуть массив с \array_flip() . А также здесь ключи не будут меняться / переиндексировать.
Также, если вы хотите использовать unset() или \array_splice() удалить несколько элементов с одинаковым значением, вы можете использовать, \array_keys() чтобы получить все ключи для определенного значения, а затем удалить все элементы.
@AlexandruRada Нет, вы сказали «не используйте это» - и это просто чепуха. Вы можете смело использовать этот метод, когда рассматриваете массив как словарь. Только если вы ожидаете последовательных числовых индексов, вам нужно использовать что-то еще. @ Александр Используйте array_splice , как описано в других ответах. @AlexandruRada Нет никакого способа, которым ты можешь иметь, array (3) < [0]=>int(0) . когда ты unset($x[2]) из $x = array(1, 2, 3, 4); Результата должен быть var_dump($x); // array(3) < [0]=> int(1) [1]=> int(2) [3]=> int(4) >(это была, вероятно, опечатка) unset может иметь несколько аргументов: void unset ( mixed $var [, mixed $. ] ) .Следует отметить, что unset() индексы останутся нетронутыми, чего и следовало ожидать при использовании строковых индексов (массив как хеш-таблица), но это может быть довольно удивительно при работе с целочисленными индексированными массивами:
Так что array_splice() можно использовать, если вы хотите нормализовать ваши целочисленные ключи. Другой вариант использует array_values() после unset() :
Стоит отметить, что когда вы используете array_splice (), вам нужно знать OFFSET, а не ключ, а смещение (!) Любого элемента, который вы хотите удалить @Tom: Для обычного массива (который постоянно индексируется целым числом) смещение является индексом. Вот где array_splice может иметь смысл (среди других). Да, конечно, но просто кое-что нужно помнить, если вы вмешиваетесь в массив перед использованием соединения С помощью простого теста удаления тонны элементов из гигантского массива, array_splice выглядит намного быстрее и требует меньше памяти. Это соответствует тому, что я ожидал: array_values (), кажется, делает копию массива, в то время как array_splice работает на месте. Аргумент array_values полезен, когда вы удаляете элементы в цикле и хотите, чтобы индексы были согласованными, но затем хотели сжать их после цикла.Это вывод из кода выше:
Теперь array_values () будет переиндексировать числовой массив, но он удалит все ключевые строки из массива и заменит их числами. Если вам нужно сохранить имена ключей (строки) или переиндексировать массив, если все ключи числовые, используйте array_merge ():
$ get_merged_values = array_merge ($ data ['res'], $ data ['check_res']); когда я печатаю этот print_r ($ get_merged_values); это отображает следующее. Array ([0] => Array ([menu_code] => 2 [menu_name] => Plant [menu_order_no] => 1) [1] => Array ([menu_code] => 3 [menu_name] => Линия [menu_order_no] => 2)) Но мне нужно получить значения menu_code и menu_name, используя $ get_merged_values ['menu_code'] и $ get_merged_values ['menu_name'] соответственно, вместо использования $ get_merged_values [0] [menu_code], $ get_merged_values [0 ] [menu_name]. помогите пожалуйста как это сделать? Было бы хорошо уточнить, что этот ответ предназначен для удаления элемента, когда вы знаете значение, а не ключ. Обратите внимание, что он удаляет только первый экземпляр значения; найти все ключи для значения, используйте array_keysЕсли у вас есть числовой индексированный массив, в котором все значения уникальны (или они не уникальны, но вы хотите удалить все экземпляры определенного значения), вы можете просто использовать array_diff (), чтобы удалить соответствующий элемент, например так:
Это отображает следующее:
В этом примере элемент со значением 'Charles' удаляется, что можно проверить с помощью вызовов sizeof (), которые сообщают о размере 4 для исходного массива и 3 после удаления.
Также для именованного элемента:
$a = array("A"=>1, "B"=>2, "C"=>"a"); print_r($a); unset($a["B"]); print_r($a); дает (в формате): Array ( [A] => 1 [B] => 2 [C] => a ), Array ( [A] => 1 [C] => a ) Кажется, вы не можете сбросить элементы массива, проиндексированные строкой (генерирует «Неустранимая ошибка: невозможно сбросить смещения строки»). Я не думаю, что это всегда имело место, но, конечно, @carpii PHP может удалять элементы из ассоциативного массива. Неустранимая ошибка возникает, когда вы пытаетесь использовать unset ($ var ['key']) в строке вместо массива. Например: $ array = array ('test' => 'value', 'another' => ' ценность', ); снята с охраны ($ массив [ 'тест']); // Удаляет элемент «test» из массива, как и ожидалось $ array = 'test'; снята с охраны ($ массив [ 'тест']); // Выдает «Фатальная ошибка: невозможно отменить смещение строки», как ожидалосьУничтожить один элемент массива
unset()
Если вам нужно переиндексировать массив:
Тогда вывод будет:
Удалить элемент из конца массива - вернуть значение удаленного элемента
mixed array_pop(array &$array)
Удалить первый элемент (красный) из массива , - вернуть значение удаленного элемента
mixed array_shift ( array &$array )
Обратите внимание, что array_shift можно удалить только первый элемент в массиве. аналогично используйте array_pop для удаления последнего элемента в массиве. Ответ применим только к первому элементу массива и не отвечает на общий вопрос. @sebweisgerber Вы правы, но я не думаю, что это неправильно, и нужно понизить этот ответ. Вопрос в том, чтобы удалить элемент без упоминания какой-либо позиции.Чтобы избежать поиска, можно поиграться с array_diff :
В этом случае не нужно искать / использовать ключ.
Если вам нужно удалить несколько значений в массиве, а записи в этом массиве являются объектами или структурированными данными, [array_filter][1] вам лучше всего. Те записи, которые возвращают true из функции обратного вызова, будут сохранены.
Ассоциативные массивы
Для ассоциативных массивов используйте unset :
Числовые массивы
Запись
Использование unset числовых массивов не приведет к ошибке, но испортит ваши индексы:
Если вам нужно удалить несколько элементов из ассоциативного массива, вы можете использовать array_diff_key () (здесь используется с array_flip () ):
unset() уничтожает указанные переменные.
Поведение unset() внутри функции может варьироваться в зависимости от типа переменной, которую вы пытаетесь уничтожить.
Если глобальная переменная находится unset() внутри функции, уничтожается только локальная переменная. Переменная в вызывающей среде сохранит то же значение, что и раньше unset() .
Ответ приведенного выше кода будет бар .
Для unset() глобальной переменной внутри функции:
Если индекс указан:
Если индекс НЕ указан:
if Условие является необходимым , потому что если index не будет найден, unset() будет автоматически удалить первый элемент массива , который не то , что мы хотим
если значение не найдено, будет удален первый элемент. добавить в тест для unset: if ($ index! == false) unset ($ arr [$ index]);Решения:
- Чтобы удалить несколько несмежных элементов, также используйте unset () :
- Чтобы удалить несколько смежных элементов, используйте array_splice () :
Дальнейшее объяснение:
Использование этих функций удаляет все ссылки на эти элементы из PHP. Если вы хотите сохранить ключ в массиве, но с пустым значением, присвойте элементу пустую строку:
Помимо синтаксиса, есть логическая разница между использованием unset () и назначением элемента. Первый говорит, This doesn't exist anymore, а второй говорит This still exists, but its value is the empty string.
Если вы имеете дело с числами, лучше выбрать 0. Таким образом, если компания остановит производство звездочки модели XL1000, она обновит свой инвентарь:
Однако, если на нем временно закончились звездочки XL1000, но в конце этой недели планировалось получить новый груз с завода, это лучше:
Если вы отменили () элемент, PHP настроит массив так, чтобы цикл все еще работал правильно. Он не сжимает массив, чтобы заполнить недостающие отверстия. Это то, что мы имеем в виду, когда говорим, что все массивы ассоциативны, даже если они кажутся числовыми. Вот пример:
Чтобы сжать массив в плотно заполненный числовой массив, используйте array_values () :
В качестве альтернативы, array_splice () автоматически переиндексирует массивы, чтобы не оставлять дыр:
Это полезно, если вы используете массив в качестве очереди и хотите удалить элементы из очереди, но при этом разрешить произвольный доступ. Чтобы безопасно удалить первый или последний элемент из массива, используйте array_shift () и array_pop () соответственно.
Читайте также: