I'm a hobby coder at best. I know enough to make helpful programs to assist me with day to day life and work (mostly with PHP/JS, some C#). I'm wanting to learn more about good coding practices. I try not to use existing frameworks, mostly so I can learn the basic language, unless I need to for something more advanced/complex.
Below is a class I wrote yesterday for handling CSV files. It's a simple class that either reads from a CSV file or writes to a CSV file. When reading/writing, it also has an option for having a header row (which in my use case, would be associated database columns). It works well and without issue.
I was hoping for some feedback on my style, and how I wrote the program, and if I may be doing anything "wrong". For example, I used to nest if statements a lot, but have been trying to reduce the nesting to make the code easier to read. One such practice I still do is, in the get_csv function, I could assign the results to a temporary variable to handle, and then assign that to the Class's results public variable. Here, I opted to assign directly, and then modify if needed. I'm not sure which would be considered better practice though.
class CSV{
    public $header_row = array(), $results = array();
    
    private $filepath = null, $ext = null;
    
    public function __construct($filepath = null){
        if($filepath)
            $this->set_filepath($filepath);
    }
    
    public function set_filepath($filepath){
        if(!$this->ValidateFilepath($filepath))
            return false;
        
        $this->filepath = $filepath;
        return true;
    }
    
    public function set_header_row($header_row){
        if(!is_array($header_row))
            return null;
        
        $this->header_row = $header_row;
    }
    
    public function write_csv($data, $header = null, $filepath = null){
        if($filepath)
            if(!$this->set_filepath($filepath))
                return false;
        
        if(!is_array($data))
            return;
        
        if(!($file = fopen($this->filepath, "w")))
            return false;
        
        if($header && is_array($header))
            fputcsv($file, $header);
        
        foreach($data as $csv_data){
            if(is_string($csv_data))
                $csv_data = array($csv_data);
            
            fputcsv($file, $csv_data);
        }
        fclose($file);
        
        return true;
    }
    
    public function get_csv($filepath = null, $header = false, $delimiter = ","){
        if($filepath)
            if(!$this->set_filepath($filepath))
                return false;
        
        if(!($file = fopen($this->filepath, "r")))
            return null;
        
        while(($data = fgetcsv($file, 10000, $delimiter)))
            array_push($this->results, $data);
        
        if($header){
            $this->header_row = array_shift($this->results);
            foreach($this->results as $index => $result)
                $this->results[$index] = array_combine($this->header_row, $this->results[$index]);
        }
        
        fclose($file);
        
        return $this->results;
        
    }
    
    private function ValidateFilepath($filepath){
        $extension = explode(".", $filepath);
        
        if(count($extension) > 2)
            return false;
        
        if($extension[1] !== "csv")
            return false;
        
        $this->ext = "csv";
        
        return true;
    }
    
}




$this->ext, why is it an instance attribute? \$\endgroup\$