Issues (137)

src/Drivers/Mysqli/Connection.php (11 issues)

1
<?php
2
3
namespace Foolz\SphinxQL\Drivers\Mysqli;
4
5
use Foolz\SphinxQL\Drivers\ConnectionBase;
6
use Foolz\SphinxQL\Drivers\MultiResultSet;
7
use Foolz\SphinxQL\Drivers\ResultSet;
8
use Foolz\SphinxQL\Exception\ConnectionException;
9
use Foolz\SphinxQL\Exception\DatabaseException;
10
use Foolz\SphinxQL\Exception\SphinxQLException;
11
12
/**
13
 * SphinxQL connection class utilizing the MySQLi extension.
14
 * It also contains escaping and quoting functions.
15
 */
16
class Connection extends ConnectionBase
17
{
18
    /**
19
     * Internal Encoding
20
     *
21
     * @var string
22
     */
23
    protected $internal_encoding;
24
25
    /**
26
     * Returns the internal encoding.
27
     *
28
     * @return string current multibyte internal encoding
29
     */
30
    public function getInternalEncoding()
31
    {
32
        return $this->internal_encoding;
33
    }
34
35
    /**
36
     * @inheritdoc
37
     */
38
    public function connect()
39
    {
40
        $data = $this->getParams();
41
        $conn = mysqli_init();
42
43
        if (!empty($data['options'])) {
44
            foreach ($data['options'] as $option => $value) {
45
                $conn->options($option, $value);
46
            }
47
        }
48
49
        set_error_handler(function () {});
50
        try {
51
            if (!$conn->real_connect($data['host'], null, null, null, (int) $data['port'], $data['socket'])) {
52
                throw new ConnectionException('Connection Error: ['.$conn->connect_errno.']'.$conn->connect_error);
53
            }
54
        } finally {
55
            restore_error_handler();
56
        }
57
58
        $conn->set_charset('utf8');
59
        $this->connection = $conn;
60
        $this->mbPush();
61
62
        return true;
63
    }
64
65
    /**
66
     * Pings the Sphinx server.
67
     *
68
     * @return bool True if connected, false otherwise
69
     * @throws ConnectionException
70
     */
71
    public function ping()
72
    {
73
        $this->ensureConnection();
74
75
        return $this->getConnection()->ping();
0 ignored issues
show
The method ping() does not exist on PDO. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

75
        return $this->getConnection()->/** @scrutinizer ignore-call */ ping();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
76
    }
77
78
    /**
79
     * @inheritdoc
80
     */
81
    public function close()
82
    {
83
        $this->mbPop();
84
        $this->getConnection()->close();
0 ignored issues
show
The method close() does not exist on PDO. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

84
        $this->getConnection()->/** @scrutinizer ignore-call */ close();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
85
86
        return parent::close();
87
    }
88
89
    /**
90
     * @inheritdoc
91
     */
92
    public function query($query)
93
    {
94
        $this->ensureConnection();
95
96
        set_error_handler(function () {});
97
        try {
98
            /**
99
             * ManticoreSearch/Sphinx silence warnings thrown by php mysqli/mysqlnd
100
             *
101
             * unknown command (code=9) - status() command not implemented by Sphinx/ManticoreSearch
102
             * ERROR mysqli::prepare(): (08S01/1047): unknown command (code=22) - prepare() not implemented by Sphinx/Manticore
103
             */
104
            $resource = @$this->getConnection()->query($query);
105
        } finally {
106
            restore_error_handler();
107
        }        
108
109
        if ($this->getConnection()->error) {
0 ignored issues
show
The property error does not seem to exist on PDO.
Loading history...
110
            throw new DatabaseException('['.$this->getConnection()->errno.'] '.
0 ignored issues
show
The property errno does not seem to exist on PDO.
Loading history...
111
                $this->getConnection()->error.' [ '.$query.']');
112
        }
113
114
        return new ResultSet(new ResultSetAdapter($this, $resource));
115
    }
116
117
    /**
118
     * @inheritdoc
119
     */
120
    public function multiQuery(array $queue)
121
    {
122
        $count = count($queue);
123
124
        if ($count === 0) {
125
            throw new SphinxQLException('The Queue is empty.');
126
        }
127
128
        $this->ensureConnection();
129
130
        $this->getConnection()->multi_query(implode(';', $queue));
0 ignored issues
show
The method multi_query() does not exist on PDO. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

130
        $this->getConnection()->/** @scrutinizer ignore-call */ multi_query(implode(';', $queue));

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
131
132
        if ($this->getConnection()->error) {
0 ignored issues
show
The property error does not seem to exist on PDO.
Loading history...
133
            throw new DatabaseException('['.$this->getConnection()->errno.'] '.
0 ignored issues
show
The property errno does not seem to exist on PDO.
Loading history...
134
                $this->getConnection()->error.' [ '.implode(';', $queue).']');
135
        }
136
137
        return new MultiResultSet(new MultiResultSetAdapter($this));
138
    }
139
140
    /**
141
     * Escapes the input with \MySQLi::real_escape_string.
142
     * Based on FuelPHP's escaping function.
143
     * @inheritdoc
144
     */
145
    public function escape($value)
146
    {
147
        $this->ensureConnection();
148
149
        if (($value = $this->getConnection()->real_escape_string((string) $value)) === false) {
0 ignored issues
show
The method real_escape_string() does not exist on PDO. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

149
        if (($value = $this->getConnection()->/** @scrutinizer ignore-call */ real_escape_string((string) $value)) === false) {

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
150
            // @codeCoverageIgnoreStart
151
            throw new DatabaseException($this->getConnection()->error, $this->getConnection()->errno);
0 ignored issues
show
The property error does not seem to exist on PDO.
Loading history...
The property errno does not seem to exist on PDO.
Loading history...
152
            // @codeCoverageIgnoreEnd
153
        }
154
155
        return "'".$value."'";
156
    }
157
158
    /**
159
     * Enter UTF-8 multi-byte workaround mode.
160
     */
161
    public function mbPush()
162
    {
163
        $this->internal_encoding = mb_internal_encoding();
0 ignored issues
show
Documentation Bug introduced by
It seems like mb_internal_encoding() can also be of type true. However, the property $internal_encoding is declared as type string. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
164
        mb_internal_encoding('UTF-8');
165
166
        return $this;
167
    }
168
169
    /**
170
     * Exit UTF-8 multi-byte workaround mode.
171
     */
172
    public function mbPop()
173
    {
174
        // TODO: add test case for #155
175
        if ($this->getInternalEncoding()) {
176
            mb_internal_encoding($this->getInternalEncoding());
177
            $this->internal_encoding = null;
178
        }
179
180
        return $this;
181
    }
182
}
183