$sql = " SELECT
device.sn.sn_number AS sn,
device.sn.sn_id AS sn_id
FROM lab.labname
INNER JOIN lab.pclab ON lab.labname.lab_id = lab.pclab.lab_id
AND device.names.dlist_id = device.list.dlist_id
WHERE device.sn.sn_delstat IS NULL
AND lab.labname.lab_id = :lab
$pc
";
Your using :lab, which is parameter binding, and then using a variable immediately after it? It’s one or the other, and preferable parameter binding to avoid sql injections.
Actually that part was okay, as $pc is a hard-coded additional SQL clause or an empty string. When it is an additional SQL clause, he is also binding a second variable. His biggest issue looks to be $pcs == !null which doesn’t read correctly, and should have been $pcs !== null and the fact that if $labs is empty it will not parse to an INT in the bindParam call very well.
This is where @vectorialpx ; seems to make a lot of sense (in my opinion) as it tackles both of those issues.