@@ -162,6 +162,12 @@ public function remove($files)
162162 } elseif (!\is_array ($ files )) {
163163 $ files = [$ files ];
164164 }
165+
166+ self ::doRemove ($ files , false );
167+ }
168+
169+ private static function doRemove (array $ files , bool $ isRecursive ): void
170+ {
165171 $ files = array_reverse ($ files );
166172 foreach ($ files as $ file ) {
167173 if (is_link ($ file )) {
@@ -170,10 +176,35 @@ public function remove($files)
170176 throw new IOException (sprintf ('Failed to remove symlink "%s": ' , $ file ).self ::$ lastError );
171177 }
172178 } elseif (is_dir ($ file )) {
173- $ this ->remove (new \FilesystemIterator ($ file , \FilesystemIterator::CURRENT_AS_PATHNAME | \FilesystemIterator::SKIP_DOTS ));
179+ if (!$ isRecursive ) {
180+ $ tmpName = \dirname (realpath ($ file )).'/. ' .strrev (strtr (base64_encode (random_bytes (2 )), '/= ' , '-. ' ));
181+
182+ if (file_exists ($ tmpName )) {
183+ try {
184+ self ::doRemove ([$ tmpName ], true );
185+ } catch (IOException $ e ) {
186+ }
187+ }
188+
189+ if (!file_exists ($ tmpName ) && self ::box ('rename ' , $ file , $ tmpName )) {
190+ $ origFile = $ file ;
191+ $ file = $ tmpName ;
192+ } else {
193+ $ origFile = null ;
194+ }
195+ }
196+
197+ $ files = new \FilesystemIterator ($ file , \FilesystemIterator::CURRENT_AS_PATHNAME | \FilesystemIterator::SKIP_DOTS );
198+ self ::doRemove (iterator_to_array ($ files , true ), true );
199+
200+ if (!self ::box ('rmdir ' , $ file ) && file_exists ($ file ) && !$ isRecursive ) {
201+ $ lastError = self ::$ lastError ;
202+
203+ if (null !== $ origFile && self ::box ('rename ' , $ file , $ origFile )) {
204+ $ file = $ origFile ;
205+ }
174206
175- if (!self ::box ('rmdir ' , $ file ) && file_exists ($ file )) {
176- throw new IOException (sprintf ('Failed to remove directory "%s": ' , $ file ).self ::$ lastError );
207+ throw new IOException (sprintf ('Failed to remove directory "%s": ' , $ file ).$ lastError );
177208 }
178209 } elseif (!self ::box ('unlink ' , $ file ) && (false !== strpos (self ::$ lastError , 'Permission denied ' ) || file_exists ($ file ))) {
179210 throw new IOException (sprintf ('Failed to remove file "%s": ' , $ file ).self ::$ lastError );
0 commit comments