Transfert SFTP en PHP fonction ssh2_sftp

Discussion dans 'Discussions Générales' démarrée par MarcMarin, Jan 9, 2017.

  1. MarcMarin

    MarcMarin New Member

    Bonjour,

    j'avais un cron qui fonctionnait bien depuis pas mal de mois pour le transfert d'un fichier texte journalier. D'un seul coup j'ai une erreur systématique sur la fonction:

    $sftpStream = @fopen($sftpUrl, 'w');

    avec $sftpUrl="ssh2.sftp://Resource id #10/transferts/2017-01-09_14-20_export.csv"

    L'administrateur du serveur cible me précise qu'il n'y eu aucune modification de leur config. Est-ce que cela pourrait provenir d'une mise à jour de PHP ou toute mise à jour liée au protocole de communication SFTP sur la plateforme PH ?

    A noter que Resource id #10 est un cast string du retour de la fonction: resource ssh2_sftp ( resource $session )

    référence code source utilisé:
    http://php.net/ssh2_sftp

    extrait source:
    if (!function_exists("ssh2_connect"))
    {
    write_file($log,"function ssh2_connect doesn't exist",true);
    fclose($log);
    die();
    }
    $connection = ssh2_connect($ftp_host, 22);
    if(!$connection)
    { // connexion
    write_file($log,"La connexion ssh2_connect $ftp_host a echoue.",true);
    fclose($log);
    die();
    }
    if (!ssh2_auth_password($connection, $ftp_user_name, $ftp_user_pass))
    { // identification
    write_file($log,"La connexion ssh2_auth_password $ftp_host a echoue. user:$ftp_user_name pass:$ftp_user_pass",true);
    fclose($log);
    ssh2_exec($connection, 'exit');
    die();
    }

    $sftp = @ssh2_sftp($connection); // initialise un sous-systeme SFTP
    if (!$sftp)
    throw new Exception("erreur sur initialisation sous-systeme SFTP");

    $target_file = $target_path . $target_file;
    $sftpUrl = "ssh2.sftp://".$sftp.$target_file;
    $sftpStream = @fopen($sftpUrl, 'w'); // creation flux pour fichier cible

    if (!$sftpStream)
    throw new Exception("erreur sur creation ficher cible: $sftpUrl");
     
  2. PH-Quentin

    PH-Quentin Administrator Membre de l'équipe

    Bonjour MarcMarin,

    Merci pour votre message, êtes-vous certain que "Resource id #10" est bien un string et non un objet contenant une erreur ? Avez-vous tenté en hardcodant l'host SFTP?

    Pourriez-vous SVP activer l'affichage des erreurs dans votre script PHP afin que nous soyons en mesure de diagnostiquer la cause du problème ? Pour ce faire, il suffit de rajouter ces deux lignes de code en dessous de la valide PHP à savoir "<?php"

    Code:
    error_reporting( E_ALL );
    @ini_set( 'display_errors', 1 );
    Une fois ces deux lignes rajoutées, je vous invite à lancer votre code et nous indiquer le message d'erreur retourné !

    J'attends votre retour (d'erreur) !
    Quentin
     
  3. MarcMarin

    MarcMarin New Member

    Bonjour et merci Quentin pour votre implication sur cette problématique.

    alors en hardcodant la fonction sous la forme:

    ssh2.sftp://user:pass@example.com:22/path/to/filename

    çà marche ! ;-) ce qui veut donc dire que la fonction
    $sftp = @ssh2_sftp($connection)
    ne renvoie pas false mais un 'Resource id #10'

    Alors que la connexion en amont se passe bien.
    $connection = ssh2_connect($ftp_host, 22);
    if(!$connection)
    ...
    if (!ssh2_auth_password($connection, $ftp_user_name, $ftp_user_pass))
    ...

    finalement pourquoi passer par ces 3 dernières fonctions alors qu’apparemment on peut directement passer tous les paramètres par ssh2.sftp

    Certains d'ailleurs se posent la question sur Resource id #10 ici:

    http://stackoverflow.com/questions/1466737/cant-get-sftp-to-work-in-php

    Concernant le log des erreurs error_reporting(E_ALL ) puisque la fin de la ligne de commande du cron contient >/dev/null 2>&1
    comment la rediriger vers un log ? j'ai essayé de remplacer /dev/null par /logs/syslog.log (puique l'espace dispose déjà d'un répertoire logs)
    Quel est la bonne pratique ?

    merci d'avance
     
  4. MarcMarin

    MarcMarin New Member

  5. PH-Quentin

    PH-Quentin Administrator Membre de l'équipe

    Rebonjour,

    Je suis content d'apprendre que nous avançons dans le debug du code !

    Lorsque que je regarde la documentation de PHP.net, je constate que la valeur de retour de la fonction ssh2_sftp n'est pas un booléen mais bien une ressource !
    [​IMG]
    Cependant un peu plus bas dans les exemples nous pouvons effectivement voir ce code qui permet de vérifier si la connexion SFTP à eu lieu avec succès ou pas:

    [​IMG]

    Après il faut bien comprendre que dans cette variable vous n'avez pas le hostname/chemin du serveur mais bien une ressource de connexion, si vous souhaitez donc initialiser une connexion avec fopen, d'après mon expérience il va falloir ré-indiquer le hostname/nom du fichier à atteindre en utilisant une autre variable de type string.

    Vous pouvez pas exemple voir le type d'une variable PHP en utilisant gettype comme ceci:

    Code:
    echo gettype($sftp), "<br>\n";
    Bien à vous,
    Quentin
     
  6. MarcMarin

    MarcMarin New Member

    je suis bien d'accord avec vous Quentin, cette construction de fonction fopen est bien curieuse

    $sftp = ssh2_sftp($connection);
    $stream = fopen("ssh2.sftp://$sftp/path/to/file", 'w');

    d'autant plus qu'on la retrouve dans plein de documents PHP y compris dans votre lien:

    $stream = @fopen("ssh2.sftp://$sftp$remote_file", 'w')

    et de plus elle m'avait pas posé de problème à moi et à d'autres.

    donc puisqu'il suffit de remplacer par une string du user/hostname, c'est ce que je vais faire et au diable les complications ! ;-)

    Merci en tout cas.
     

Partager cette page