<?php
function fputcsv_content($fp, $array, $delimiter=",", $eol="\n") 
{
    static $find = ["\\r","\\n"];
    static $replace = ["\r","\n"];
    static $cycles_count = 0;
    $cycles_count++;
    
    $array = array_map(function($value) use($delimiter) {
      return clean_value($value, $delimiter);
    }, $array);
    $eol = str_replace($find, $replace, $eol);

    $line = implode($delimiter, $array) . $eol;
    
    $return_value = $line;//fputs($fp, $line);

    /** purposefully free up the ram **/
    $line = null;
    $eol = null;
    $array = null;

    /** trigger gc_collect_cycles() every 250th call of this method **/
    if($cycles_count % 250 === 0) gc_collect_cycles();

    return $return_value;
}

/** Use a second function so the GC can be triggered here
  * when it returns the value and all intermediate values are free.
  */
function clean_value($value, $delimeter) 
{
   /**
     *  use static values to prevent reassigning the same
     *  values to the stack over and over
     */
   static $regex = []; 
   static $find = "\r\n";
   static $replace = "\n";
   static $quote = '"';
   if(!isset($regex[$delimeter])) {
      $regex[$delimeter] = "/[$delimiter\"\n\r]/";
   }
   $value = trim($value);
   $value = str_replace($find, $replace, $value);
   if(preg_match($regex[$delimeter], $value)) {
        $value = $quote.str_replace($quote, '""', $value).$quote;
   }
   return $value;
}

echo fputcsv_content(null, ['foo', "bar\n\rbaz", "hello world!",'test " test']);