First and last char is alfabetic, A-Za-z.
This is because I have seen websites that will demand this.

Always is generated 1 Upper, 1 Lower, 1 Number and 1 Symbol.
The remaining 4 chars are of any type.

This gives a password that is reasonable secure.
I use this generator for my own passwords.

To remember passwords I use Last Pass https://www.lastpass.com/

<?php

// The Characters
// 8 chars excluded: "&'<>\` and space
$symbol = '!#$%()*+,-./:;=?@[]^_{|}~';  // 25 chars
$number = '0123456789';                 // 10 chars
$upper  = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; // 26 chars
$lower  = 'abcdefghijklmnopqrstuvwxyz'; // 26 chars
$alfa   = $upper.$lower;                // 52 chars
$chars  = $symbol.$number.$upper.$lower;// 87 chars

// Password generator for 10 chars
$pw = '';
$ord = str_shuffle('12345678');
$pw[0] = $alfa[mt_rand(0,51)];
$pw[$ord[0]] = $symbol[mt_rand(0,24)];
$pw[$ord[1]] = $number[mt_rand(0,9)];
$pw[$ord[2]] = $upper[mt_rand(0,25)];
$pw[$ord[3]] = $lower[mt_rand(0,25)];
$pw[$ord[4]] = $chars[mt_rand(0,86)];
$pw[$ord[5]] = $chars[mt_rand(0,86)];
$pw[$ord[6]] = $chars[mt_rand(0,86)];
$pw[$ord[7]] = $chars[mt_rand(0,86)];
$pw[9] = $alfa[mt_rand(0,51)];

// Display result
echo '<p style="font-family:\'Courier New\'">';
echo '1234567890123456';
echo '<br>';
echo $pw;
echo '</p>';

exit();

    I just felt like coming up with something more OOP, and threw this together. Not claiming it's great, just something different. 🙂

    <?php
    
    header('Content-Type: text/plain');
    $pwd = new PasswordGenerator(10,12);
    echo $pwd->password();
    
    class PasswordGenerator
    {
        private $min;
        private $max;
        // edit this for the symbols you want to allow
        private $symbols = array('.', ',', '!', '?', '$', '-', '_', '+', '@', '&', '*');
        private $password;
    
    public function __construct($min=8, $max=10)
    {
        if($max < $min or $min < 4) {
            throw new Exception("Invalid min/max password length");
        }
        $this->min = $min;
        $this->max = $max;
        $this->generate();
    }
    
    public function generate()
    {
        $password = array();
        // make sure we get at least one of each type
        $types = array('int', 'lower', 'upper', 'symbol');
        foreach($types as $type) {
            $password[] = $this->$type();
        }
        // emphasize letters a bit more for the rest
        $types[] = 'lower';
        $types[] = 'upper';
        $length = rand($this->min, $this->max);
        while(count($password) < $length) {
            $type = $types[array_rand($types)];
            $password[] = $this->$type();
        }
        shuffle($password);
        $this->password = implode('', $password);
        return $this->password;
    }
    
    public function password()
    {
        return $this->password;
    }
    
    private function int()
    {
        return rand(0, 9);
    }
    
    private function lower()
    {
        return chr(rand(97, 122));
    }
    
    private function upper()
    {
        return chr(rand(65, 90));
    }
    
    private function symbol()
    {
        return $this->symbols[array_rand($this->symbols)];
    }
    }
    

      This is a version that is a bit better.

      First and last is alfa, A-Za-z.
      The rest is
      - 2 Upper case
      - 2 Lower case
      - 2 Numbers
      - 2 Symbols

      <?php
      
      // The Characters
      // 8 chars excluded: "&'<>\` and space
      $symbol = '!#$%()*+,-./:;=?@[]^_{|}~';  // 25 chars
      $number = '0123456789';                 // 10 chars
      $upper  = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; // 26 chars
      $lower  = 'abcdefghijklmnopqrstuvwxyz'; // 26 chars
      $alfa   = $upper.$lower;                // 52 chars
      
      // Password Generator 10 chars
      $pw = '';
      $ord = str_shuffle('12345678');
      $pw[0] = $alfa[mt_rand(0,51)];
      $pw[$ord[0]] = $symbol[mt_rand(0,24)];
      $pw[$ord[1]] = $symbol[mt_rand(0,24)];
      $pw[$ord[2]] = $number[mt_rand(0,9)];
      $pw[$ord[3]] = $number[mt_rand(0,9)];
      $pw[$ord[4]] = $upper[mt_rand(0,25)];
      $pw[$ord[5]] = $upper[mt_rand(0,25)];
      $pw[$ord[6]] = $lower[mt_rand(0,25)];
      $pw[$ord[7]] = $lower[mt_rand(0,25)];
      $pw[9] = $alfa[mt_rand(0,51)];
      
      // Display result
      echo '<p style="font-family:\'Courier New\'">';
      echo '1234567890123456';
      echo '<br>';
      echo $pw;
      echo '</p>';
      
      exit();
      
        Write a Reply...